R数据表:移动列表类型的行

时间:2016-07-23 01:24:28

标签: r data.table

我有一个带有list类型的data.table:

x = data.table(k = seq(1:5), l = list(c(4,5)))
> x
   k   l
1: 1 4,5
2: 2 4,5
3: 3 4,5
4: 4 4,5
5: 5 4,5

我现在正试图将l值改为1

x[, m:=shift(l, 1)]
> x
   k   l     m
1: 1 4,5 NA, 4
2: 2 4,5 NA, 4
3: 3 4,5 NA, 4
4: 4 4,5 NA, 4
5: 5 4,5 NA, 4

这会在'内产生转变。列表,而不是列表。(旁白:不清楚行NA出现2-5的原因。) 想要得到这样的东西的方法是什么:

x[magic]
> x
   k   l  m
1: 1 4,5 NA
2: 2 4,5 4,5
3: 3 4,5 4,5
4: 4 4,5 4,5
5: 5 4,5 4,5

2 个答案:

答案 0 :(得分:3)

您可以使用手动班次,如下所示。

x[, m := c(NA_real_, head(l, -1L))]

导致

   k   l   m
1: 1 4,5  NA
2: 2 4,5 4,5
3: 3 4,5 4,5
4: 4 4,5 4,5
5: 5 4,5 4,5

对于更大的班次,你可以自己动手。

mshift <- function(var, n) c(NA[1:n], head(var, -n))

然后用它来移动两个地方。

x[, m := mshift(l, 2)]

从原始数据中得出

   k   l   m
1: 1 4,5  NA
2: 2 4,5  NA
3: 3 4,5 4,5
4: 4 4,5 4,5
5: 5 4,5 4,5

显然,这个功能非常基本,只向右移动(向下)。如果您愿意,可以调整功能以向相反方向移动并添加一些类检查/匹配。

答案 1 :(得分:2)

使用shift,一个选项是在'l'序列上获得shift,根据该子集'l'并将其分配给新列'm'。默认情况下,shift会返回fill = NA。因此,这些元素在{m'中为NULL,我们可以replaceNA(如果需要)或者删除这些元素也可以使用{{1 }}

is.null

或者正如@Frank所提到的,我们可以在'i'中指定逻辑索引,同时仅将'm'更新为x[, m := l[shift(seq_along(l))]][, m := lapply(m, function(x) replace(x, is.null(x), NA))] x # k l m #1: 1 4,5 NA #2: 2 4,5 4,5 #3: 3 4,5 4,5 #4: 4 4,5 4,5 #5: 5 4,5 4,5 ,仅用于'i'中指定的那些元素子集,并且效率更高。 / p>

NA_real_

或者以紧凑的方式,我们可以将x[, m := l[shift(seq_along(l))]][sapply(m, is.null), m := .(.(NA_real_))] 更改为fill并在开头添加0。如果NA大于1,请使用shift复制NA并在开头追加。

rep