用指定的列数按行计算累积总和

时间:2018-08-16 09:38:52

标签: r cumsum

下面您可以看到我有一个较大的桌子的示例

library(data.table)
input  <- data.table(ID     = c("A", "B"),
                     Para   = c(2.8, 5),
                     Value1 = c(50, 80),
                     Value2 = c(80, 40),
                     Value3 = c(80, 100),
                     Value4 = c(60, 10),
                     Value5 = c(40, 80))

我要实现的是添加一个列,并在Para列中指定接下来x列的累积和。但是,如果逗号后面有数字,则该列中的值应由数字调整。

因此对于第一行(参数= 2.8),结果应为

1*50 + 1*80 + 0.8*80 = 194

第二行(参数= 5)的结果应为

1*80 + 1*40 + 1*100 + 1*10 + 1*80 = 310

决赛桌应该像

output <- cbind(input, Result = c(194, 310))

我想到的是将Para值2.8拆分为5个数字的百分比矢量,所以将整个范围都划分了。

c(1, 1, .8, 0, 0)

将列Value1:Value5与此向量相乘,然后将所有Value1:Value5相加。但是我不知道如何将2.8分解为这样的向量,也许还有一个我不知道的更好的解决方案。谢谢。

4 个答案:

答案 0 :(得分:5)

这是一种解决方案,可将数据保留为宽格式,并使用Reduce()计算“加权行总和”:

library(data.table)
input[, Cumul := {
  tmp <- c(rep(1, Para), Para %% 1)
  mul <- replace(rep(0, ncol(.SD)), seq_along(tmp), tmp)
  Reduce(sum, .SD * mul)
}, .SDcols = Value1:Value5, by = ID]
input[]
   ID Para Value1 Value2 Value3 Value4 Value5 Cumul
1:  A  2.8     50     80     80     60     40   194
2:  B  5.0     80     40    100     10     80   310

这将适用于.SDcols指定的任意数量的列或Para较大的列。

答案 1 :(得分:1)

您可以使用模除法%/%和除法其余部分来创建乘法矢量,然后在apply调用中使用所有内容,例如:

apply(input, MARGIN = 1, function(x) {
  multiplier <- as.numeric(x["Para"])
  multiplier_long <- c(rep(1, multiplier %/% 1), multiplier %% 1)[1:5]
  multiplier_long[is.na(multiplier_long)] <- 0
  sum(as.numeric(x[-c(1, 2)]) * multiplier_long)
})

# [1] 194 310

答案 2 :(得分:1)

$(this).html($(this).html().replace( /#(?![a-fA-F0-9]{6})([a-zA-Z0-9]+)/g, '<a class="hashtag" href="' + SP_source() + '?hashtag=$1">#$1</a>')

答案 3 :(得分:0)

如果您想将Para分成5个值的向量,可以尝试执行以下操作:

input %>%
  select(ID,Para) %>%
  slice(rep(1:n(), each = 5)) %>%
  group_by(ID) %>%
  mutate(rn = 1:n()) %>%
  mutate(Para = if_else( (Para - rn)>0, 1.0, 
                        if_else(Para - rn > -1, Para - lag(rn), 0))) %>%
  select(-rn)

给出:

   ID     Para
   <chr> <dbl>
 1 A     1    
 2 A     1    
 3 A     0.800
 4 A     0    
 5 A     0    
 6 B     1    
 7 B     1    
 8 B     1    
 9 B     1    
10 B     1