【发布时间】:2017-03-09 16:45:33
【问题描述】:
我有一个这样的data.table
ID event meas1 meas2 meas3
1: 1 A 100 500 900
2: 1 B 200 600 1000
3: 1 C 300 700 1100
4: 2 A 400 800 1200
5: 3 A 500 900 1300
6: 3 B 600 1000 1400
每个观察都由其 ID 区分,因此我希望一个 ID 对应一行。
ID A_meas1 B_meas1 C_meas1 A_meas2 B_meas2 C_meas2 A_meas3 B_meas3 C_meas3
1 1 100 200 300 500 600 700 900 1000 1100
2 2 400 NaN NaN 800 NaN NaN 1200 NaN NaN
3 3 500 600 NaN 900 1000 NaN 1300 1400 NaN
有没有办法有效地做到这一点,因为我有一个 10 mio 的 data.table。行?
目前我尝试了这个:
library(data.table)
library(dplyr)
library(tidyr)
dt %>%
mutate(key = paste(event, "meas1", sep="_")) %>%
spread(key, meas1) %>%
mutate(key = paste(event, "meas2", sep="_")) %>%
spread(key, meas2) %>%
mutate(key = paste(event, "meas3", sep="_")) %>%
spread(key, meas3) %>%
select(-event) %>%
group_by(ID) %>%
summarise(A_meas1=mean(A_meas1, na.rm=T),
B_meas1=mean(B_meas1, na.rm=T),
C_meas1=mean(C_meas1, na.rm=T),
A_meas2=mean(A_meas2, na.rm=T),
B_meas2=mean(B_meas2, na.rm=T),
C_meas2=mean(C_meas2, na.rm=T),
A_meas3=mean(A_meas3, na.rm=T),
B_meas3=mean(B_meas3, na.rm=T),
C_meas3=mean(C_meas3, na.rm=T)) -> data
但恐怕买不起这么多内存。
感谢您的想法和对我的代码和/或我的想法的评论。谢谢。
【问题讨论】:
-
使用 dtplyr 包,您应该能够在 data.table 上使用 tidyr 语法并获得接近 data.table 的性能。
-
如果你愿意迁移到data.table,语法是
dcast(dt, ID ~ event, value.var = paste0("meas", 1:3), fun = mean, na.rm = TRUE),但我猜有类似spread的代码。 -
@Frank 没有与
spread类似的代码,因为它被设计为出于某种原因忽略函数的存在。 -
其实我的数据中不需要使用mean()。我只是用它来折叠行。人们还可以以某种方式为每个 ID 组的每列选择唯一的非 nan 值。
标签: r data.table dplyr tidyr