使用data.table对R中的序列求和

时间:2020-10-30 00:03:15

标签: r data.table

我正在尝试使用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],则代码将按预期执行。

4 个答案:

答案 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)

如果您对代码进行逐行操作,那么您的代码将起作用,因此每个startend一次代表一个值。

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