As of v1.9.6 (on CRAN 19 Sep 2015), data.table
can cast multiple value columns simultaneously:
library(data.table)
dcast(setDT(df), DeviceID ~ rowid(DeviceID), value.var = c("ContentID", "Use"))
DeviceID ContentID_1 ContentID_2 Use_1 Use_2
1: D1 C1 C2 0.6784913 0.3021474
2: D2 C1 C2 0.6957901 0.6458492
3: D3 C1 C2 0.8350400 0.3622916
Changing column order
The result contains the expected columns but in a different order. dcast()
creates the new columns grouped by value.var
.
The OP has not indicated whether the exact column order is of importance or not. However, the expected result can be reproduced exactly by changing the column order by reference, i.e., without copying the whole data object using setcolorder()
:
cols <- c("ContentID", "Use")
wide <- dcast(setDT(df), DeviceID ~ rowid(DeviceID), value.var = cols)
new_col_order <- CJ(seq_len(uniqueN(df$ContentID)), cols)[, paste(V2, V1, sep = "_")]
setcolorder(wide, new_col_order)
wide
ContentID_1 Use_1 ContentID_2 Use_2 DeviceID
1: C1 0.6784913 C2 0.3021474 D1
2: C1 0.6957901 C2 0.6458492 D2
3: C1 0.8350400 C2 0.3622916 D3
CJ()
is a cross join of the row ids with the value.vars to create the column names in the desired order.
I have filed a feature request on GitHub to optionally change the order of columns in dcast()
.
Data
library(data.table)
df <- fread(
" DeviceID ContentID Use
D1 C1 0.678491346
D1 C2 0.302147374
D2 C1 0.695790066
D2 C2 0.645849165
D3 C1 0.83503997
D3 C2 0.3622916"
)