我正在寻找有关如何在我的r脚本中提高长if / else循环效率的建议。我还希望尽可能地适应未来的发展,因为它的范围可能会随着时间而改变。
使用其他语言的旧代码,我正在为大型项目自动化报告过程。在这个项目中,我有多个“中心”来基于数据库的子集创建报告。现在,我使用一个长的示例循环来完成此操作,如下所示:
df$ReportName <- 0
df$new_centername[is.na(df$new_centername)] <- 0
for (i in 1:nrow(df)){
if (df$new_centername[i] == 1){
df$ReportName[i] <- "Center A"
} else if (df$new_centername[i] == 2){
df$ReportName[i] <- "Center B"
} else if (df$new_centername[i] == 3){
df$ReportName[i] <- "Center C"
} else if (df$new_centername[i] == 4){
df$ReportName[i] <- "Center D"
} else if (df$new_centername[i] == 5){
df$ReportName[i] <- "Center E"
} else if (df$new_centername[i] == 6){
df$ReportName[i] <- "Center F"
}
...
df
是常规数据帧,new_centername
指定数据行所属的居中位置,并全部以数字编码。
随着时间的流逝,我希望可以添加更多的中心。我假设有一种方法可以将这些中心存储在列表中,然后创建一个循环访问列表的循环。这样,在添加新中心时,我只需要将其名称添加到列表中。
SampleList <- list("Center A", "Center B", "Center C", ...)
for (i in 1:nrow(df)){
for (j in 1:length(SampleList)){
if (df$new_centername[i] == 1){
df$ReportName[i] <- SampleList[j]
}
}
}
非常感谢您帮忙整理最好的逻辑和适当的语法以进行优化! 谢谢
答案 0 :(得分:2)
根据所示的代码,我们可以直接假设“ new_centername”中的值是一个从1开始的序列来直接执行此操作,它可以用作填充其他值的索引。下面,我们使用paste0
创建一个字符串向量,以使'Center A'将替换或获得'new_centername'为1,'Center B',2等的位置。概念,直到“ F中心”才创建。
df$new_centername <- paste0("Center ", LETTERS[1:6])[df$new_centername]
由于OP提到替换值中没有模式并且索引也不同,所以有效的方法(也在@JasonAizkalns的注释中建议)将是创建键/值数据集,然后与原始数据连接
keyval <- data.frame(key = c(5, 12, 13, 25),
val = c('ASD', 'BDF', 'ANF', 'SDT'), stringsAsFactors = FALSE)
library(data.table)
setDT(df)[keyval, new_name := val, on = .(new_center_name = key)]
df