我有一个简单的问题:我有两个函数。它们都使用
if(...) {expression}
if(...) {expression}
if(...) {expression}
代替
if(...) {expression}
else{
if(...) {expression}
else {expression}
}
但两者只有一个有效。
第一个效果很好:
test.1 <- function (y) {
if(y == 1){z <- 10}
if(y == 2){z <- 20}
if(y == 5){z <- 50}
return(z)
}
第二个不工作:
df.1 <- data.frame(A = 1:3)
df.2 <- data.frame(A = 4:6)
df.3 <- data.frame(A = 7:9)
test.2 <- function (num) {
x <- with(if(num == 1){df.1}
if(num == 2){df.2}
if(num == 3){df.3}, {sum(A)})
return(x)
}
我需要使用if else表达式来让第二个函数工作:
test.2 <- function (num) {
x <- with(if(num == 1){df.1}
else {if(num == 2){df.2}
else {df.3}
}, {sum(A)})
return(x)
}
我真的不明白为什么这个多重if语句在第一种情况下工作,而不是在第二种情况下!??
第二个例子不起作用,因为with
的第一个参数应该是"一个环境,一个列表,一个数据帧,或一个整数,如sys.call
"(参见参数部分?with
)。
您可以通过将if语句包装在花括号中来避免"unexpected end of line"错误:
test.2 <- function (num) {
x <- with({if(num == 1)df.1
if(num == 2)df.2
if(num == 3)df.3}, {sum(A)})
return(x)
}
但是这仍然不起作用,因为括号内有3个表达式,只有最后求值的表达式才会返回。嗯,如果num==3
…但我们可以做得更好。您可以在这里使用switch
:
test.2 <- function (num) {
with(switch(num, df.1, df.2, df.3), sum(A))
}
您最好使用switch
:
test.2 <- function(num){
x <- with(switch(num,df.1,df.2,df.3),{sum(A)})
return(x)
}
test.2(1)
[1] 6
test.2(2)
[1] 15
test.2(3)
[1] 24
两个问题:首先,with
在其第一个参数中期望一个表达式(计算为data.frame或环境)。您可以通过将这些if
语句包装在花括号中以使其成为单个表达式来修复此问题。
test.2 <- function (num) {
x <- with(
{
if(num == 1){df.1}
if(num == 2){df.2}
if(num == 3){df.3}
},
sum(A)
)
return(x)
}
第二个问题是在找到匹配后没有从表达式返回。因此,当num
为1时,满足第一个if条件并返回df.1
。然后计算下一个if
表达式,由于num
不是2,因此返回NULL
。类似地,第三个if
表达式返回NULL
。因为这是块中的最后一个表达式,所以返回的就是它。你实际上有
with(NULL, sum(A))
与sum(A)
相同,因为A
不存在而抛出错误。
你可以做另一个修改,比如
test.2 <- function (num) {
x <- with(
{
if(num == 1)return(df.1)
if(num == 2)return(df.2)
if(num == 3)return(df.3)
},
sum(A)
)
return(x)
}
(当num
是1,2或3时,这是有效的),但你最好使用switch
代替,就像James建议的。
如果所有数据帧都一致命名,如示例中所示,那么有比使用switch
更好的解决方案。使用paste
获取变量名,然后调用get
。
test.3 <- function(num) with(get(paste("df", num, sep = ".")), sum(A))
test.3(1) #6
test.3(2) #15
test.3(3) #24
三个expression
都有可能执行。
if(...) {expression}
if(...) {expression}
if(...) {expression}
在下面的例子中,只执行一个expression
。
if(...) {expression}
else
{
if(...) {expression}
else
{
expression
}
}