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
,则执行do2
。 cond
的剩余元素被忽略。
这不是 ifelse
的行为,正如您从第一个示例中注意到的那样。在ifelse (cond, do1, do2)
中,do1
和do2
中的相关部分将根据cond
中的哪些元素是TRUE
或FALSE
来完成。
下面的代码应该做你想做的事
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]]
})
我有一个数据帧列表:
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
,则执行do2
。 cond
的剩余元素被忽略。
这不是 ifelse
的行为,正如您从第一个示例中注意到的那样。在ifelse (cond, do1, do2)
中,do1
和do2
中的相关部分将根据cond
中的哪些元素是TRUE
或FALSE
来完成。
下面的代码应该做你想做的事
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]]
})