Я хотел бы рассчитать некоторые сводные статистики и выполнить разные регрессии по группам в таблице данных и получить результаты в "широком" формате (т.е. одна строка для каждой группы с несколькими столбцами). Я могу сделать это несколькими шагами, но кажется, что нужно сделать все сразу.
Рассмотрим этот пример данных:
set.seed=46984
dt <- data.table(ID=c(rep('Frank',5),rep('Tony',5),rep('Ed',5)), y=rnorm(15), x=rnorm(15), z=rnorm(15),key="ID")
dt
# ID y x z
# 1: Ed 0.2129400 -0.3024061 0.845335632
# 2: Ed 0.4850342 -0.5159197 -0.087965415
# 3: Ed 1.8917489 1.7803220 0.760465271
# 4: Ed -0.4330460 -2.1720944 0.973812545
# 5: Ed 0.7685060 0.7947470 1.279761200
# 6: Frank 0.4978475 -0.2906851 0.568101004
# 7: Frank 0.6323386 -0.5596599 1.537133025
# 8: Frank -0.8243218 -0.4354885 0.057818033
# 9: Frank 1.2402488 0.3229422 0.005995249
#10: Frank 0.2436210 -0.2651422 0.349532173
#11: Tony 0.4179568 0.1418463 0.142380549
#12: Tony 0.7036613 0.4402572 0.141237901
#13: Tony -0.1978720 -0.9553784 0.480425820
#14: Tony -1.7269375 -0.1881292 0.370583351
#15: Tony 1.1064903 0.4375014 -0.798221750
Скажем, я хочу получить медиану по ID, выполнить линейную регрессию по y ~ x по ID и выполнить линейную регрессию по y ~ x + z по ID. Здесь я получаю медиану:
dt.med <- dt[,list(y.med=median(y)),by=ID]
dt.med
# ID y.med
#1: Ed 0.4850342
#2: Frank 0.4978475
#3: Tony 0.4179568
И благодаря этому ответу от @DWin, здесь я получаю два отдельных набора коэффициентов регрессии как столбцы по ID:
dt.reg.1 <- dt[,as.list(coef(lm(y ~ x))), by=ID]
dt.reg.1
# ID (Intercept) x
#1: Ed 0.63057884 0.5482373
#2: Frank 0.69720351 1.3813007
#3: Tony 0.08588421 1.0179131
dt.reg.2 <- dt[,as.list(coef(lm(y ~ x + z))), by=ID]
dt.reg.2
# ID (Intercept) x z
#1: Ed 0.8262577 0.5587170 -0.2582699
#2: Frank 0.4317538 2.7221024 1.1807442
#3: Tony 0.1494439 0.3166547 -1.2029693
Теперь мне нужно присоединиться к трем наборам результатов и переименовать столбцы:
dt.ans <- dt.med[dt.reg.1][dt.reg.2]
setnames(dt.ans,c("ID","y.med","reg.1.c0","reg.1.c1","reg.2.c0","reg.2.c1","reg.2.c2"))
Наконец, вот пример желаемого вывода для примера:
dt.ans
# ID y.med reg.1.c0 reg.1.c1 reg.2.c0 reg.2.c1 reg.2.c2
#1: Ed 0.4850342 0.63057884 0.5482373 0.8262577 0.5587170 -0.2582699
#2: Frank 0.4978475 0.69720351 1.3813007 0.4317538 2.7221024 1.1807442
#3: Tony 0.4179568 0.08588421 1.0179131 0.1494439 0.3166547 -1.2029693
Кажется неэффективным вычислять три результата, присоединяться к ним, а затем переименовывать столбцы. Кроме того, мои фактические таблицы довольно большие, поэтому я хотел бы убедиться, что я не использую слишком много системной памяти. Возможно ли это сделать в рамках одного "оператора data.table"? Или, что более важно, можно ли это сделать более эффективно?
Я пробовал разные вещи. Вот один неудачный пример, который дает медиану, но игнорирует коэффициенты регрессии:
dt[,as.list(median(y),coef(lm(y ~ x))), by=ID]
# ID V1
#1: Ed 0.4850342
#2: Frank 0.4978475
#3: Tony 0.4179568