我手头的任务是弄清楚如何根据列的累加和拆分数据帧。
作为一个例子,下面是一个数据帧
df & lt; - data.frame (a1 = c("X1","X2","X3","X4","X5","X6","X7","X8","X9","X10"),A2 = rnorm(20, mean=5, sd=2))
df2 <- df[order(df$a2),] # df按a2从小到大排序
我如何创建一个数据帧列表,其中a2列在每个df2中总和为10,而没有任何行重复?
每行的结果取决于前一行的值,因此需要迭代方法。将其封装在函数中可能是最简单的:
split_sum <- function(data, column, split_by = 10) {
x <- data[[as.character(match.call()$column)]]
group <- current_group <- value <- 0
for(i in seq(nrow(data))) {
group[i] <- current_group
value <- x[i] + value
if(value > split_by) {
current_group <- current_group + 1
value <- 0
}
}
setNames(split(data, group), NULL)
}
测试一下,我们有:
df <- data.frame(a1 = c("X1", "X2", "X3", "X4", "X5",
"X6", "X7", "X8", "X9", "X10"),
a2 = sort(rnorm(20, mean = 10, sd = 2)))
split_sum(df, a2, 10)
#> [[1]]
#> a1 a2
#> 1 X1 6.232476
#> 2 X2 7.466659
#>
#> [[2]]
#> a1 a2
#> 3 X3 7.674123
#> 4 X4 7.946872
#>
#> [[3]]
#> a1 a2
#> 5 X5 8.202970
#> 6 X6 8.340281
#>
#> [[4]]
#> a1 a2
#> 7 X7 9.046769
#> 8 X8 9.323847
#>
#> [[5]]
#> a1 a2
#> 9 X9 9.569602
#> 10 X10 9.955981
#>
#> [[6]]
#> a1 a2
#> 11 X1 10.58773
#>
#> [[7]]
#> a1 a2
#> 12 X2 10.69006
#>
#> [[8]]
#> a1 a2
#> 13 X3 10.7256
#>
#> [[9]]
#> a1 a2
#> 14 X4 11.61281
#>
#> [[10]]
#> a1 a2
#> 15 X5 11.80578
#>
#> [[11]]
#> a1 a2
#> 16 X6 11.91369
#>
#> [[12]]
#> a1 a2
#> 17 X7 12.40917
#>
#> [[13]]
#> a1 a2
#> 18 X8 13.11021
#>
#> [[14]]
#> a1 a2
#> 19 X9 14.00975
#>
#> [[15]]
#> a1 a2
#> 20 X10 14.11547
但是这个函数被写成了这样一种方式,例如,只有当总和达到50时才中断:
split_sum(df, a2, 50)
#> [[1]]
#> a1 a2
#> 1 X1 6.232476
#> 2 X2 7.466659
#> 3 X3 7.674123
#> 4 X4 7.946872
#> 5 X5 8.202970
#> 6 X6 8.340281
#> 7 X7 9.046769
#>
#> [[2]]
#> a1 a2
#> 8 X8 9.323847
#> 9 X9 9.569602
#> 10 X10 9.955981
#> 11 X1 10.587733
#> 12 X2 10.690059
#>
#> [[3]]
#> a1 a2
#> 13 X3 10.72560
#> 14 X4 11.61281
#> 15 X5 11.80578
#> 16 X6 11.91369
#> 17 X7 12.40917
#>
#> [[4]]
#> a1 a2
#> 18 X8 13.11021
#> 19 X9 14.00975
#> 20 X10 14.11547
由reprex包(v2.0.1)创建于2022-06-17