lapply 和多个条件参数(ifelse 与 if else 系列)

lapply and multiple conditional arguments (ifelse versus if else series)

我有一个数据帧列表:

count1<-(seq(1:10)) 
count2<-(seq(5:14))    
other<-c("a","b","c","d","e","f","g","h","i","j")
a<-seq(1,20,by=2)
b<-seq(1,30,by=3)
c<-seq(1,40,by=4)

df1<-data.frame(cbind(a,other,count1))
df2<-data.frame(cbind(b,other,count1))
df3<-data.frame(cbind(c,other,count2))

sept<-list(df1,df2,df3)

我想在每个数据框中创建一个附加变量,其值以 count1/count2 的值为条件。对于 lapply,ifelse 适用于两种情况:

sept2<-lapply(sept,function(x) {
     mx<-max(x[[3]]);
     d3<-(mx-2);
     ifelse (d3 < x[[3]], x[[4]] <-4, x[[4]] <-0);
 })

this2
[[1]]
 [1] 0 0 0 0 0 0 0 0 4 4

[[2]]
 [1] 0 0 0 0 0 0 0 0 4 4

[[3]]
 [1] 0 0 0 0 0 0 0 0 4 4

但是,将相同的基本结构与 if else 系列一起使用是行不通的。

this3<-lapply(this,function(x) {
    mx<-max(x[[3]]);
    d3<-(mx-2);
    d2<-(mx-4);
    d1<-(mx-6);
    if (d3<x[[3]] && x[[3]]<=mx) {
        x[[4]] <-4
    } else if (d2<x[[3]] && x[[3]]<=d3){
        x[[4]] <-3
        } else if (d1<x[[3]] && x[[3]]<=d2){
            x[[4]] <-2
        }else {
            x[[4]] <-1
        }
})

this3

[[1]]
[1] 1

[[2]]
[1] 1

[[3]]
[1] 1

我不明白为什么 R 在使用 ifelse 时知道将函数应用于 x[[3]] 的每个观察,但在使用 if else 系列时却不知道。为什么这两种情况不同?

我认为,当您编写 if(cond) {do1} else {do2} 时,只会评估 cond 中的第一个元素。例如,如果cond[1] == TRUE,则执行do_1,如果是FALSE,则执行do2cond 的剩余元素被忽略。

这不是 ifelse 的行为,正如您从第一个示例中注意到的那样。在ifelse (cond, do1, do2)中,do1do2中的相关部分将根据cond中的哪些元素是TRUEFALSE来完成。


下面的代码应该做你想做的事

this <- sept 
this3 <-lapply(this, function(x) {
  mx <- max(x[[3]]);
  d3 <- mx-2
  d2 <- mx-4
  d1 <- mx-6
  x[[4]] <- rep(1, length(x[[3]]))
  x[[4]][d3<x[[3]] & x[[3]]<=mx] <- 4
  x[[4]][d2<x[[3]] & x[[3]]<=d3] <- 3
  x[[4]][d1<x[[3]] & x[[3]]<=d2] <- 2
  x[[4]]
})