我正在尝试使用r中的data.table对一系列序列求和。这个想法是,我将一个开始索引和一个结束索引定义为表中的列,然后为“开始索引和结束索引之间的序列之和”创建第三列。
series = c(1,2,3,4,5,6)
a = data.table(start=c(1,2,3),end=c(4,5,6))
a[,S := sum(series[start:end])]
a
预期结果:
start end S
1: 1 4 10
2: 2 5 14
3: 3 6 18
实际结果:
Warning messages:
1: In start:end : numerical expression has 3 elements: only the first used
2: In start:end : numerical expression has 3 elements: only the first used
> a
start end S
1: 1 4 10
2: 2 5 10
3: 3 6 10
我在这里想念什么?如果我只是执行[,S:= start + end],则代码将按预期执行。
答案 0 :(得分:4)
一种选择是用Map
遍历“开始”,“结束”列,获取相应元素的顺序(:
),获取sum
和{{ 1}},在unlist
列中将其分配( list
)到新列
:=
-输出
a[, S := unlist(Map(function(x, y) sum(x:y), start, end))]
a
# start end S
#1: 1 4 10
#2: 2 5 14
#3: 3 6 18
的操作数未向量化,即,它在任一侧仅需一个操作数,这就是它显示警告的原因
答案 1 :(得分:3)
也许您可以尝试使用cumsum
,如下所示,它允许您在data.table
内应用矢量化运算
cs <- cumsum(series)
a[,S := cs[end]-c(0,cs)[start]]
给出
start end S
1: 1 4 10
2: 2 5 14
3: 3 6 18
答案 2 :(得分:3)
您可以使用算术级数公式:
a[, S := (end - start + 1) * (start + end) / 2]
礼物:
start end S
1: 1 4 10
2: 2 5 14
3: 3 6 18
答案 3 :(得分:2)
如果您对代码进行逐行操作,那么您的代码将起作用,因此每个start
和end
一次代表一个值。
library(data.table)
a[,S := sum(series[start:end]), 1:nrow(a)]
a
# start end S
#1: 1 4 10
#2: 2 5 14
#3: 3 6 18