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)][]