用sapply按组计算费率

时间:2019-05-28 14:07:59

标签: r data.table data-manipulation sapply

我有这样的数据:
这只是我创建的虚假数据:

# dt
Col1      Col2   Col3   Col4
2014/1/1  A        10   1
2014/4/1  A        15   1.5
2015/1/1  A        15   3
2015/4/1  A        30   4
2014/1/1  B        20   2
2014/4/1  B        30   6
2015/1/1  B        40   10
2015/4/1  B        80   16

我想要什么:

Col1      Col2   Col3   Col4   Col3.R   Col4.R
2014/1/1  A        10   1      1        1
2014/4/1  A        15   1.5    1.5      1.5
2015/1/1  A        15   3      1.5      3
2015/4/1  A        30   4      3        4
2014/1/1  B        20   2      1        1
2014/4/1  B        30   6      3/2      3
2015/1/1  B        40   10     2        5
2015/4/1  B        80   16     4        8

新列Col3.R由每个组col3下的Col2的值除以每个组中的第一个值来计算。与col4.R相同。

我尝试下面的代码:

dt[, sapply(.SD, function(x) R = x / x[1]), .SDcols = 3:4, by = .(Col2)]

如何保留原始列?我需要为on使用参数data.table吗?

数据:

dt <- fread("    Col1      Col2   Col3   Col4
2014/1/1  A        10   1
2014/4/1  A        15   1.5
2015/1/1  A        15   3
2015/4/1  A        30   4
2014/1/1  B        20   2
2014/4/1  B        30   6
2015/1/1  B        40   10
2015/4/1  B        80   16", header = T)
dt$Col3 <- as.numeric(dt$Col3)

2 个答案:

答案 0 :(得分:4)

使用lapplypaste0创建新列

library(data.table)

dt[, paste0("col", 3:4, ".R") := lapply(.SD, 
           function(x) x / x[1]), .SDcols = 3:4, by = .(Col2)]

dt
#       Col1 Col2 Col3 Col4 col3.R col4.R
#1: 2014/1/1    A   10  1.0    1.0    1.0
#2: 2014/4/1    A   15  1.5    1.5    1.5
#3: 2015/1/1    A   15  3.0    1.5    3.0
#4: 2015/4/1    A   30  4.0    3.0    4.0
#5: 2014/1/1    B   20  2.0    1.0    1.0
#6: 2014/4/1    B   30  6.0    1.5    3.0
#7: 2015/1/1    B   40 10.0    2.0    5.0
#8: 2015/4/1    B   80 16.0    4.0    8.0

答案 1 :(得分:1)

我们可以按'Col2'分组,在@GeneratedValue(strategy=GenerationType.AUTO) @Column(name = "id") private Integer merchId; 中指定感兴趣的列,遍历Data.table的子集,然后除以x的 merchantEntity = merchantRepository.saveAndFlush(entity); // still returns null merchantEntity = merchantRepository.save(entity); merchantRepository.flush(); MerchantEntity toBeUpdatedMerchantEntity = merchantRepository.findOne(merchantEntity.getId()); // still returns null 元素

.SDcols

或使用first

dt[, paste0(names(dt)[3:4],  ".R") := 
    lapply(.SD, function(x) x/first(x)), .SDcols = 3:4, by = .(Col2)] 
dt
#       Col1 Col2 Col3 Col4 Col3.R Col4.R
#1: 2014/1/1    A   10  1.0    1.0    1.0
#2: 2014/4/1    A   15  1.5    1.5    1.5
#3: 2015/1/1    A   15  3.0    1.5    3.0
#4: 2015/4/1    A   30  4.0    3.0    4.0
#5: 2014/1/1    B   20  2.0    1.0    1.0
#6: 2014/4/1    B   30  6.0    1.5    3.0
#7: 2015/1/1    B   40 10.0    2.0    5.0
#8: 2015/4/1    B   80 16.0    4.0    8.0