У меня есть таблица data.table со следующей структурой:
num_id value
1000 A1
1001 A1
1000 A2
1000 A3
1001 A54
1002 A55
1001 A100
, и я хотел бы превратить ее в dt вида
num_id A1 A2 A3 A54 A55 A100
1000 1 1 1 0 0 0
1001 1 0 0 1 0 1
1002 0 0 0 0 1 0
Я думал, что это будет легко используя dcast
. На ум пришла формула dcast(dt, numid~value)
. Однако он пожаловался на Cross product of elements provided to CJ() would result in 4850158203 rows which exceeds .Machine$integer.max == 2147483647
. Это больше, чем количество ожидаемых строк, потому что у меня около 500 000 уникальных идентификаторов. После запуска тестов на меньшей таблице данных кажется, что вызов dcast
сохраняет идентификаторы в точности такими, как они есть, заменяя столбец значений вектором столбцов, в котором только 1 элемент не равен нулю. Это мало помогает, поскольку отсутствует важный этап агрегации / группировки.
Я написал следующий код, который работает, но работает медленно и запутанно. Есть ли способ сделать это за один вызов dcast?
futurecolumns=unique(dt$value)
aggregated=dt[,list(list(value)), by=num_id]
out=t(sapply(aggregated$V1, function(x){futurecolumns %in% x}))
out=as.data.table(out*1)
out$num_id=aggregated$num_id
setnames(out, c(futurecolumns, "num_id"))