使用 sapply 按组计算费率
Calculate rate by group with 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)]
如何保留原来的栏目?我需要为 data.table
使用参数 on
吗?
数据:
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)
使用lapply
和paste0
创建新列
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
我们可以按 'Col2' 分组,在 .SDcols
中指定感兴趣的列,遍历 Data.table 的子集并除以 x[ 的 first
元素=15=]
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
或使用tidyverse
library(tidyverse)
dt %>%
group_by(Col2) %>%
mutate_at(3:4, list(R = ~ ./first(.)))
# A tibble: 8 x 6
# Groups: Col2 [2]
# Col1 Col2 Col3 Col4 Col3_R Col4_R
# <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#1 2014/1/1 A 10 1 1 1
#2 2014/4/1 A 15 1.5 1.5 1.5
#3 2015/1/1 A 15 3 1.5 3
#4 2015/4/1 A 30 4 3 4
#5 2014/1/1 B 20 2 1 1
#6 2014/4/1 B 30 6 1.5 3
#7 2015/1/1 B 40 10 2 5
#8 2015/4/1 B 80 16 4 8
我有这样的数据:
这只是我创建的假数据:
# 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)]
如何保留原来的栏目?我需要为 data.table
使用参数 on
吗?
数据:
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)
使用lapply
和paste0
创建新列
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
我们可以按 'Col2' 分组,在 .SDcols
中指定感兴趣的列,遍历 Data.table 的子集并除以 x[ 的 first
元素=15=]
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
或使用tidyverse
library(tidyverse)
dt %>%
group_by(Col2) %>%
mutate_at(3:4, list(R = ~ ./first(.)))
# A tibble: 8 x 6
# Groups: Col2 [2]
# Col1 Col2 Col3 Col4 Col3_R Col4_R
# <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#1 2014/1/1 A 10 1 1 1
#2 2014/4/1 A 15 1.5 1.5 1.5
#3 2015/1/1 A 15 3 1.5 3
#4 2015/4/1 A 30 4 3 4
#5 2014/1/1 B 20 2 1 1
#6 2014/4/1 B 30 6 1.5 3
#7 2015/1/1 B 40 10 2 5
#8 2015/4/1 B 80 16 4 8