如果在for循环内

时间:2019-07-25 18:54:22

标签: r for-loop if-statement

我偶然发现了一篇关于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 )。

有人可以解释这种行为吗?以及如何修改我的循环始终正确? 任何解释高度赞赏!

2 个答案:

答案 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