我有一个简单的问题:我有两个功能。他们都使用
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语句在第一种情况下起作用而在第二种情况下不起作用!??
答案 0 :(得分:4)
第二个例子不起作用,因为with
的第一个参数应该是“sys.call
中的环境,列表,数据框或整数”(参见参数)第?with
}节。
通过将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)
}
但是这仍然不起作用,因为括号内有3个表达式,只返回最后一个计算表达式。好吧,如果num==3
它会起作用......但我们可以做得更好。您可以在此使用switch
:
test.2 <- function (num) {
with(switch(num, df.1, df.2, df.3), sum(A))
}
答案 1 :(得分:1)
您最好使用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
答案 2 :(得分:1)
两个问题:首先,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时有效),但与James建议相比,使用switch
要好得多。
如果所有数据框都一致地命名,如示例中所示,那么比使用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
答案 3 :(得分:0)
所有三个expression
都可能执行。
if(...) {expression}
if(...) {expression}
if(...) {expression}
在下面的情况下,只会执行一个expression
。
if(...) {expression}
else
{
if(...) {expression}
else
{
expression
}
}