我偶然发现了一篇关于for循环中ifelse语句的帖子:
How to create new variables using loop and ifelse statement
var1 <- c(0,0,1,2)
var2 <- c(2,2,2,0)
var3 <- c(0,0,0,2)
var4 <- c(1,2,2,2)
df<-as.data.frame(cbind(var1,var2,var3,var4))
df
var1 var2 var3 var4
0 2 0 1
0 2 0 2
1 2 0 2
2 0 2 2
基于帖子,输出为:
var1 var2 var3 var4 new
0 2 0 1 1
0 2 0 2 0
1 2 0 2 1
2 0 2 2 0
因为如果一行中的任何元素中有1,则列(新)中的对应行将为1,否则它将为0
我写了这样的东西:
for (i in 1:nrow(df)){
if(mean(df[i,] == 1) == 0){
df$new[i]<- 0}
else{
df$new[i]<- 1
}}
但是,它给出了以下输出:
var1 var2 var3 var4 new
0 2 0 1 1
0 2 0 2 1
1 2 0 2 1
2 0 2 2 1
如果我将代码if(mean(df [i,] == 1)== 0)修改为if(mean(df [i] == 1)== 0),那么它可以工作,但是在其他情况下,如果我通过在特定位置包含1来修改数据帧,则if(mean(df [i,] == 1)== 0)是正确的,而不是if(mean(df [i] == 1)== 0 )。
有人可以解释这种行为吗?以及如何修改我的循环始终正确? 任何解释高度赞赏!
答案 0 :(得分:1)
基于提供的数据
var1 <- c(0,0,1,2)
var2 <- c(2,2,2,0)
var3 <- c(0,0,0,2)
var4 <- c(1,2,2,2)
df<-as.data.frame(cbind(var1,var2,var3,var4))
get_1 <- apply(df, 1, function(x) any(x %in% c(1)))
vec = c()
for (i in get_1){
if(i == 'TRUE'){
vec <- c(vec, 1)
}
else if(i == 'FALSE'){
vec <- c(vec, 0)
}
}
df$new <- vec
df
#OUTPUT
# var1 var2 var3 var4 new
# 0 2 0 1 1
# 0 2 0 2 0
# 1 2 0 2 1
# 2 0 2 2 0
答案 1 :(得分:1)
矢量化解决方案总是更好:
df$new <- as.integer(rowSums(df == 1) > 0)
对于您的代码,我认为它可以工作。在测试时,您的数据框中可能仍然有df$new
,这导致逻辑混乱。我无法重现错误。
var1 <- c(0,0,1,2)
var2 <- c(2,2,2,0)
var3 <- c(0,0,0,2)
var4 <- c(1,2,2,2)
df<-as.data.frame(cbind(var1,var2,var3,var4))
df2 <- df
df2
var1 var2 var3 var4
1 0 2 0 1
2 0 2 0 2
3 1 2 0 2
4 2 0 2 2
df2$new <- as.integer(rowSums(df == 1) > 0)
for (i in 1:nrow(df)){
if(mean(df[i,] == 1) == 0){
df2$new[i]<- 0}
else{
df2$new[i]<- 1
}}
df2
var1 var2 var3 var4 new
1 0 2 0 1 1
2 0 2 0 2 0
3 1 2 0 2 1
4 2 0 2 2 0