R中的Ifelse缺少变量

时间:2016-06-23 08:26:15

标签: r if-statement

1.使用以下列:

s1 <- c(1,2,4,2,3,4,2,3)
s2 <- c(2,3,1,1,4,3,3,5)
s3 <- c(3,4,2,4,1,2,1,4)
s5 <- c(4,1,3,3,2,1,4,2)
s6 <- c(5,5,5,5,5,5,5,1)
samples <- cbind(s1, s2, s3, s5, s6)
samples <- data.frame(samples)

2。我生成以下代码:

samples$r1<-ifelse(samples$s1==1,"s1", 
ifelse(samples$s2==1,"s2",
ifelse(samples$s3==1,"s3",
ifelse(samples$s5==1,"s5",        
ifelse(samples$s6==1,"s6",       
"99")
))))

3。这给了我以下结果。

 s1 s2 s3 s4 s5 r1
1  1  2  3  4  5 s1
2  2  3  4  1  5 s5
3  4  1  2  3  5 s2
4  2  1  4  3  5 s2
5  3  4  1  2  5 s3
6  4  3  2  1  5 s5
7  2  3  1  4  5 s3
8  3  5  4  2  1 s6

4。到目前为止,这么好...... 5.然后我在变量s4 ....的代码中添加另一个条件。

samples$r1<-ifelse(samples$s1==1,"s1", 
ifelse(samples$s2==1,"s2",
ifelse(samples$s3==1,"s3",
**ifelse(samples$s4==1,"s4",**        
ifelse(samples$s5==1,"s5",
ifelse(samples$s6==1,"s6",       
"99")
)))))

6。 ...数据集中不存在。我现在得到以下结果

 s1 s2 s3 s5 s6   r1
1  1  2  3  4  5   s1
2  2  3  4  1  5 <NA>
3  4  1  2  3  5   s2
4  2  1  4  3  5   s2
5  3  4  1  2  5   s3
6  4  3  2  1  5 <NA>
7  2  3  1  4  5   s3
8  3  5  4  2  1 <NA>

7。没有重新发送错误消息,但是存在一个新变量s4 数据集中不存在的代码在输出中产生错误,因为我得到r1 = NA,当我应该期望与上面第3点中的输出相同时。在代码中包含一个不存在的变量导致了这个错误,我很难找到解决它的方法。在ORACLE SQL中,我会使用“case when exists”但是在R中的SQLDF包中不能使用此选项。 7.这是现实生活问题的简化版本,我需要编写能够流畅运行的代码,即使输入变量会不时变化。因此,虽然列S4不在此数据集中,但它可能出现在我运行此代码的下一个数据集中,因此我必须为这种可能性腾出空间。

  1. 我试图使用:

    样品$ R1&LT; -ifelse(存在(样本S1 $ == 1, “S1”), ifelse(存在(样品S2 $ == 1, “S2”), ifelse(存在(样本$ S3 == 1, “S3”), 的 ifelse(存在(样品S4 $ == 1, “S4”),
    ifelse(存在(样本$ S5 == 1, “S5”), ifelse(存在(样本$ S6 == 1, “S6”),
    “99”) )))))

  2. 但这显然过于简单,并没有帮助我解决这个问题。我还在很大程度上搜索了Stack Overflow而没有找到解决这个问题的方法。 R中存在的“存在”并不是我能告诉我的,而是我正在寻找的帮助。

2 个答案:

答案 0 :(得分:1)

如果您没有使用嵌套的ifelse语句,可以尝试

dt$r1 <- apply(dt, 1, function(x) {
  names(which(x == 1))
})

   s1 s2 s3 s5 s6 r1
1:  1  2  3  4  5 s1
2:  2  3  4  1  5 s5
3:  4  1  2  3  5 s2
4:  2  1  4  3  5 s2
5:  3  4  1  2  5 s3
6:  4  3  2  1  5 s5
7:  2  3  1  4  5 s3
8:  3  5  4  2  1 s6

或者您可以使用data.table

library(data.table)
dt <- data.table(samples)
dt[, r1 := colnames(dt)[max.col(-dt)]]

答案 1 :(得分:0)

首先:在实际问题中使用Martin Schmelzer的解决方案之一。

但是回答你提出的问题:

第(8)项中的代码无法运行,因为ifelse()需要3个参数(并且您只提供了2个)而exists()没有执行我认为您期望它做的事情(如你的代码所暗示的。)

将参数传递给exists()一个字符串,其中包含要查找的变量的名称(以及可选择的搜索环境或对象),并返回是否存在具有该名称的变量,以及从来没有它的价值在您的示例中,它将是exists("s4", samples),而不是exists(samples$s4),但它只会返回FALSE

> teste <- list(x = 1:3)
> teste
$x
[1] 1 2 3
> exists("x", teste)
[1] TRUE
> exists("teste$x")
[1] FALSE

get0()更有可能做你想做的事情

> get0("teste$x")
NULL
> get0("x", teste)
Error in get0("x", teste) : argumento 'envir' inválido
> get0("x", as.environment(teste))
[1] 1 2 3
> get0("y", as.environment(teste))
NULL
> get0("y", as.environment(teste), ifnotfound = "")
[1] ""

所以,回到你的例子,

getme <- 
    function(x) 
        get0(
            x, 
            as.environment(samples), 
            ifnotfound = rep(0,nrow(samples))
        )
samples$r1 <- 
    ifelse(
        getme("s1") == 1,
        "s1", 
        ifelse(
            getme("s2") == 1,
            "s2",
            ifelse(
                getme("s3") == 1,
                "s3",
                ifelse(
                    getme("s4") == 1,
                    "s4",
                    ifelse(
                        getme("s5") == 1,
                        "s5",
                        ifelse(
                            getme("s6") == 1,
                            "s6",       
                            "99"
                        )
                    )
                )
            )
        )
    )

给出了期望的结果

  s1 s2 s3 s5 s6 r1
1  1  2  3  4  5 s1
2  2  3  4  1  5 s5
3  4  1  2  3  5 s2
4  2  1  4  3  5 s2
5  3  4  1  2  5 s3
6  4  3  2  1  5 s5
7  2  3  1  4  5 s3
8  3  5  4  2  1 s6

所以,总而言之,你想要的既不实用也不优雅,但是可行。