我有一个很大的data.table,它已从csv文件中读取(基本上是SQL查询的结果)。每个记录都有20个字段的几组,这些字段是特定事物(例如,特定付款类型)的年度数字。这是简化版,只有5行,每年有3个字段
> dt <- data.table(id=1:5, dob = sample(1950:2000, 5), cont01=11:15, cont02=21:25, cont03=31:35)
> dt
id dob cont01 cont02 cont03
1: 1 1981 11 21 31
2: 2 1954 12 22 32
3: 3 1985 13 23 33
4: 4 1986 14 24 34
5: 5 1970 15 25 35
我希望至少获得一个向量列表,每个记录一个向量:
list (c(11, 21, 31), c(12, 22, 32), c(13, 23, 33), c(14, 24, 34), c(15, 25, 35))
尽管如此,但我认为我希望向量可以作为新列出现在数据表中。甚至更理想的情况是,我需要向量是固定长度的,每个元素都要在特定年龄付款。因此,第一行的这三列的向量为
> c(rep(0, 5), 11, 21, 31, rep(0, 38))
向量中的第一个年龄是15岁,最后一个是60岁。
从this question看来,列表中有data.table列是可能的。但是我无法弄清楚如何从同一行的其他列创建内容。
例如:
> dt[1, list(list(c(.SD))), .SDcols=c("cont2011", "cont2012", "cont2013")]
V1
1: <list>
> dt[1, list(list(c(.SD))), .SDcols=c("cont2011", "cont2012", "cont2013")][,V1]
[[1]]
[[1]]$`cont2011`
[1] 11
[[1]]$cont2012
[1] 21
[[1]]$cont2013
[1] 31
似乎并没有真正提供我想要的东西,因为我看不到如何在V1
列的内容上完成漂亮的矢量操作。 (我将需要对得到的向量做很多欧几里德距离类型的事情)。
有什么想法吗?有关替代方法的建议? data.table中大约有1300万行,我希望能够做到5组20个(左右)列。
答案 0 :(得分:2)
您可以使用以下代码创建一个新的列表列。
dt[, newcol := .(.(c(cont01, cont02, cont03))), by = id]
# id dob cont01 cont02 cont03 newcol
# 1: 1 1993 11 21 31 11,21,31
# 2: 2 1960 12 22 32 12,22,32
# 3: 3 1977 13 23 33 13,23,33
# 4: 4 1955 14 24 34 14,24,34
# 5: 5 1959 15 25 35 15,25,35
给出相同结果的另一个选项是
dt[, newcol := .(.(unlist(.SD))), by = id, .SDcols = names(dt)[3:5]]
函数.
只是list
内的[.data.table
的别名。
答案 1 :(得分:1)
我们通过数据的split
索引和row
将数据集的列unlist
子集
subdt <- as.data.frame(dt[, 3:5, with = FALSE])
lapply(split(subdt, row(subdt)), unlist, use.names = FALSE)
或者在对列进行子集设置之后,进行转置将其转换为matrix
,然后通过split
的{{1}}索引将col
转换为
matrix