如何解决R:如何使用数字索引循环变量名如在 Stata 中 条件:other_var(i) 函数的 TRUE 部分777 函数的 FALSE 部分
我一直在尝试在 R 中复制以下 Stata 循环失败:
forvalues i=1/10 {
replace var`i'= a if other_var`i'==b
}
到目前为止,我认为这是最接近的尝试:
for(i in 1:10) {
df <- df %>%
mutate(get(paste("var",i,sep="")) =
ifelse(get(paste("other_var",sep=""))==b,a,get(paste("var",sep=""))))
}
但我收到以下错误:
Error: unexpected '=' in:
"survey_data <- survey_data %>%
mutate(paste("offer","_accepted",sep="") ="
如果我将变量更改为一个简单的变量名称,它就可以工作,所以我猜我的代码对于“突变的右侧”是可以的,但是由于某种原因它不适用于“左侧”。
解决方法
这个解决方案非常不雅,但我认为这正是你想要的。
var1 <- "x"
var2 <- "y"
var3 <- "z"
other_var1 <- 1
other_var2 <- 0
other_var3 <- 1
df <- data.frame(var1,other_var1,var2,other_var2,var3,other_var3)
for(i in 1:3){
var_name <- paste("df$var",i,sep = "")
other_var_name <- paste("df$other_var",sep = "")
if (eval(parse(text = other_var_name)) == 1){
assign(var_name,"a")
}
}
这里有三个关键要素。首先 paste()
函数在循环的当前迭代中创建变量的名称。其次,eval(parse(foo))
组合引用名称作为字符串存储在 foo
中的实际变量。第三,使用 assign()
为变量赋值(而不是使用 <-
)。
这看起来像 FAQ 7.21。
该答案最重要的部分是最后说要使用列表。
尝试在 R 中处理一组全局变量会导致代码复杂,难以阅读,甚至更难调试。
如果您改为将这些变量放在一个列表中,那么您可以按名称或位置访问它们,并使用 lapply
或 purrr
包(tidyverse 的一部分)之类的工具来处理列表中的所有内容列表(或使用 map_at
中的 map_if
或 purrr
的列表中的某些内容)。
如果告诉我们更多有关您要完成的任务的信息,我们或许可以提供一个更简单的示例来说明如何做到这一点。
,您可以执行以下操作:
df <- structure(list(var1 = c(1,2,3,4),var2 = c(1,var3 = c(1,var4 = c(1,other_var1 = c(1,1,0),other_var2 = c(0,1),other_var3 = c(1,other_var4 = c(0,1)),class = "data.frame",row.names = c(NA,-4L))
# var1 var2 var3 var4 other_var1 other_var2 other_var3 other_var4
# 1 1 1 1 1 1 0 1 0
# 2 2 2 2 2 0 1 1 0
# 3 3 3 3 3 1 0 0 1
# 4 4 4 4 4 0 1 0 1
## Values to replace based on OP original question
a <- 777
b <- 1
## Iter along all four variables avaible in df
for (i in 1:4) {
df <- within(df,{
assign(paste0("var",i),ifelse(get(paste0("other_var",i)) %in% c(b),## Condition
a,## Value if Positive
get(paste0("var",i)) )) ## Value if Negative
})
}
结果如下:
# var1 var2 var3 var4 other_var1 other_var2 other_var3 other_var4
# 1 777 1 777 1 1 0 1 0
# 2 2 777 777 2 0 1 1 0
# 3 777 3 3 777 1 0 0 1
# 4 4 777 4 777 0 1 0 1
该解决方案看起来不像单行解决方案,但实际上是一个,非常密集的一个;因此,让我们看看它的基础组件是如何工作的。
within()
:我不想重复其他人已经很好地解释的内容,所以对于 within()
的用法,我温和地参考您 here。
:assign(paste0("var",X)
部分。
这里我关注的是 @han-tyumi 在他的回答中所做的,这意味着使用 paste0()
恢复变量的名称并使用 X
为它们分配值(待解释) {1}} 函数。
让我们谈谈assign()
。
在我引用 X
之前。实际上,assign(paste0("var",X)
等于 X
。
在ifelse(get(paste0("other_var",a,get(paste0("var",i)) )
内部:
条件:
首先,我在循环时将函数 ifelse()
与 other_var(i)
组合起来,恢复变量 get()
(其中 i = 1,4)的值。然后,我使用 paste0()
运算符检查分配给变量 %in%
(在我的示例中为数字 1)的值是否包含在变量 b
中;这将根据条件是否满足生成 TRUE 或 FALSE。
other_var(i)
函数的 TRUE
部分。
如果满足条件,这是最简单的部分,然后分配 ifelse()
(在我的示例中等于 a
)。
777
函数的 FALSE
部分。
ifelse()
:这是变量本身的值(意思是,如果条件不满足,则保持变量不变)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。