我有一个带有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
答案 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
,我们可以replace
到NA
(如果需要)或者删除这些元素也可以使用{{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