r - 如何在 R 中通过多个组运行循环
问题描述
我有一个包含多个变量的数据集,我想将两列的值逐行求和。如果总和低于设定的阈值,我想用总和值替换第二列(正在求和)的值。但是,我想按组执行此操作。
我的数据框设置了 18 个不同的列,包括“Closed_Grid”、“Closed_Sets”、“BestAvail”、“Best_Sets”和“Best_Distance”。“BestAvail”、“Best_Sets”和“Best_Distance”重复用于第二最佳、第三、第四和第五。我正在使用此信息来确定最终目标位置(第 18 列“Dest_Grid”),该位置将根据“Closed_Sets”和目标集的条件求和填充来自“BestAvail”、“2nd_Best”等的网格索引(最佳、第二等)。最后,如果两列的总和 <=150,则该网格单元(“BestAvail”)将是“Dest_Grid”。如果总和 > 150,那么它将转到下一个块并计算“Closed_Sets”之间的新总和
因此,为了帮助简化这一点,我的数据集的样本(和子集)如下所示:
Closed_Grid Closed_Sets BestAvail Best_Sets
GY38 72.875 GX38 91.75
GY37 87.125 GX38 91.75
GY36 39.875 GX38 91.75
GZ38 29 GX38 91.75
GZ37 80 GX38 91.75
GY35 2.375 GX38 91.75
GZ36 125.25 GX38 91.75
GZ35 29.875 GX38 91.75
GY39 17.5 GX39 54.125
HA35 34.375 GZ33 30.5
GZ41 109.625 GZ42 76.76
GY41 82.28571 GZ42 76.75
HA41 87.5 GZ42 76.75
GZ40 104.75 GZ42 76.75
GY40 60.625 GZ42 76.75
HA40 79.875 GZ42 76.75
GZ39 51.57143 GZ42 76.75
HA39 71 GZ42 76.75
我首先使用“BestAvail”和“Distance”(从最小到最大)排列我的数据:
Destination <- Destination %>% arrange(BestAvail, BestDistance)
这是一个重要的顺序,因为与 BestAvail 距离最小的 Closed_Grid 优先进入该网格。
所以现在我想在一个组内按行对“Closed_Sets”和“Best_Sets”求和(即“BestAvail”相同)。每当行的总和小于阈值 (150) 时,“Best_Sets”值将替换为先前的总和。所以,我想要的输出是这样的:
Closed_Grid Closed_Sets BestAvail Best_Sets BestSum
GY38 72.875 GX38 91.75 164.6250
GY37 87.125 GX38 91.75 178.8750
GY36 39.875 GX38 91.75 131.625
GZ38 29 GX38 131.625 160.625
GZ37 80 GX38 131.625 211.625
GY35 2.375 GX38 131.625 134.00
GZ36 125.25 GX38 134.00 259.250
GZ35 29.875 GX38 134.00 163.8750
GY39 17.5 GX39 54.125 71.625
HA35 34.375 GZ33 30.5 64.875
GZ41 109.625 GZ42 76.75 186.375
GY41 82.28571 GZ42 76.75 159.03571
HA41 87.5 GZ42 76.75 164.25
GZ40 104.75 GZ42 76.75 181.5
GY40 60.625 GZ42 76.75 137.375
HA40 79.875 GZ42 137.375 217.25
GZ39 51.57143 GZ42 137.375 188.94643
HA39 71 GZ42 137.375 208.375
我可以通过使用这个循环部分地实现这一点:
for (i in 1:nrow(Destination)){
Destination$BestSum[i] <- sum(Destination$Closed_Sets[i], Destination$Best_Sets[i])
if (Destination$BestSum[i] <= 150){
Destination [i:length(Destination),"Best_Sets"] <- Destination$BestSum[i]
}
}
但是,此代码将所有“Best_Sets”的值设为 134,并且在“BestAvail”值更改时不会重新启动,这反过来又会弄乱以下所有总和。最终,我试图对保持在 150 以下的组中的每个“Closed_Set”进行条件累积和。
这是我正在研究的模型的一部分,它将有超过 150 个单独的数据集贯穿其中,所有数据集都具有不同的长度和值。这段特殊的代码还需要遍历第二、第三等集合,因此它需要是可以重复的,并且变量很容易改变。
我尝试在循环中使用 unique() 函数,尝试让我自己的函数在 dplyr 中使用(这将是理想的!),尝试使用重置函数进行不同的累积和,并且此时已经搜索了数百个线程。
我对 R 和编程比较陌生,并且很难弄清楚如何做到这一点。我已经就与此相关的每个可能问题进行了多次讨论,但似乎无法让它在我的数据上起作用。
我希望我想要实现的目标是有意义的。
提前致谢!
解决方案
注意:下面的 R 代码不是很惯用,可能会很慢。我不建议您将这种样式用于常见任务。
# build the data frame
Closed_Grid = c(
"GY38",
"GY37",
"GY36",
"GZ38",
"GZ37",
"GY35",
"GZ36",
"GZ35",
"GY39",
"HA35",
"GZ41",
"GY41",
"HA41",
"GZ40",
"GY40",
"HA40",
"GZ39",
"HA39"
)
Closed_Sets = c(
72.875,
87.125,
39.875,
29,
80,
2.375,
125.25,
29.875,
17.5,
34.375,
109.625,
82.28571,
87.5,
104.75,
60.625,
79.875,
51.57143,
71
)
BestAvail = c(
"GX38",
"GX38",
"GX38",
"GX38",
"GX38",
"GX38",
"GX38",
"GX38",
"GX39",
"GZ33",
"GZ42",
"GZ42",
"GZ42",
"GZ42",
"GZ42",
"GZ42",
"GZ42",
"GZ42"
)
Best_Sets = c(
91.75,
91.75,
91.75,
91.75,
91.75,
91.75,
91.75,
91.75,
54.125,
30.5,
76.76,
76.75,
76.75,
76.75,
76.75,
76.75,
76.75,
76.75
)
dat <- data.frame(
Closed_Grid, Closed_Sets, BestAvail, Best_Sets,
stringsAsFactors = FALSE
)
# allocate a vector; this makes the for() loop use significantly
# less memory, see https://adv-r.hadley.nz/perf-improve.html#avoid-copies
dat$BestSum <- NA_real_
# split the data frame to work on one group of BestAvail at a time
Destination <- split(dat, factor(dat[["BestAvail"]]))
Destination <- lapply(Destination, function(dat) {
for (i in seq_len(nrow(dat))) {
BestSum <- rowSums(dat[i, c("Closed_Sets", "Best_Sets")])
dat[i, "BestSum"] <- BestSum
if (as.integer(i) > 1L) {
if (BestSum < 150.0) {
dat[i+1:(nrow(dat) - i), "Best_Sets"] <- dat[i, "BestSum"]
}
}
}
dat
})
# recombine
Destination <- do.call(rbind, Destination)
Destination
这段代码可能会很慢。如果您在大型数据集上运行它,则可能值得用 C++ 编写它。
推荐阅读
- nginx - Nginx 将 forum.example.com 重定向到 example.com
- java - 我在 Blue J 上绘制了一个带有 2 个变量的 StickFigure。我需要为更多实例变量添加声明
- c# - 使用 SearchHashtag Instashaper 的问题
- python - pip install PyAudio:错误:命令“cl.exe”失败:没有这样的文件或目录
- email - 使用带有 uuencode 的 cat 通过 unix 发送电子邮件
- vue.js - 错误:找不到模块“webpack-cli/bin/config-yargs”
- r - 基于 R 中的另一列创建从列中提取的列分组字符串文本
- java - 如何使用 Rxjava 预填充 android 房间数据库
- jenkins - Jenkins Pipeline 将参数作为 shell 脚本参数传递
- pandas - 熊猫的嵌套循环