For the sake of completeness, here is a solution which uses data.table
's convenient rowid()
function.
The crucial point of the question is that the reshaping solely depends on the row position of value
within each (year
, product
) group. rowid(year, product)
numbers the rows within each group. So, reshaping essentially becomes a one-liner:
library(data.table)
dcast(setDT(df1), year + product ~ rowid(year, product, prefix = "col_"))
year product col_1 col_2 col_3 col_4 col_5
1: 2015 PROD A test1 blue 50 66 66
2: 2018 PROD A test3 red 55 88 90
3: 2018 PROD B test2 yellow 70 88.8 88.8
Note that rowid()
takes a prefix
parameter to ensure that the resulting column names are syntactically correct.
Caveat: This solution assumes that year
and product
form a unique key for each group.
Data
The data are read as posted by th OP without any modifications to the data. However, this requires a few lines of post-processing:
library(data.table)
df1 <- fread("
2015 PROD A test1
2015 PROD A blue
2015 PROD A 50
2015 PROD A 66
2015 PROD A 66
2018 PROD B test2
2018 PROD B yellow
2018 PROD B 70
2018 PROD B 88.8
2018 PROD B 88.8
2018 PROD A test3
2018 PROD A red
2018 PROD A 55
2018 PROD A 88
2018 PROD A 90",
header = FALSE, col.names = c("year", "product", "value"), drop = 2L)[
, product := paste("PROD", product)][]