R是逻辑不连贯

时间:2015-07-09 10:05:14

标签: r if-statement

我想要使用isTRUE根据ifs和elses编写一个新变量并且遇到困难。我希望有一个像

这样的条件
if (isTRUE(t$a > t$b)) {
  t$c <- 0
} else if (isTRUE(t$a < t$b)) {
  t$c <- 1
} else {
  t$c <- 2
}

考虑以下数据:

t<-as.data.frame(c(1:5))
names(t)<-"a"
t$b<-c(5:1)

运行上面的代码会使c值始终为2,即isTRUE(t$a > t$b)isTRUE(t$a < t$b)始终为FALSE。

3 个答案:

答案 0 :(得分:5)

阅读isTRUE的帮助:

 ‘isTRUE(x)’ is an abbreviation of ‘identical(TRUE, x)’, and so is
 true if and only if ‘x’ is a length-one logical vector whose only
 element is ‘TRUE’ and which has no attributes (not even names).

这可能不是你想要的。

我猜你想要一个向量,t$c如果t$a>t$b则为0,如果为t$a<t$b则为1,否则为2。在R中,我们可以在单个矢量化操作中执行此操作:

设置更简单:

> t = data.frame(a=1:5, b=5:1)
> t
  a b
1 1 5
2 2 4
3 3 3
4 4 2
5 5 1

如果a> b,则c为0,如果a,则为1

> t$c=2-((t$a>t$b)+(t$a!=t$b))
> t
  a b c
1 1 5 1
2 2 4 1
3 3 3 2
4 4 2 0
5 5 1 0

逻辑运算(>!=等)沿向量运算,并以数字方式评估为1表示TRUE,0表示FALSE。如果您尝试为t$c键入我的表达式部分,您应该了解这一切是如何协同工作的。

如果你不喜欢那种棘手的布尔算法,那么几个嵌套的ifelse函数就可以工作:

t$c = ifelse(t$b>t$a, 1, ifelse(t$b==t$a,2,0))

这具有更具可读性的优点 - 如果b> a,则其为1,否则如果b = a则其为2,否则为0.注意ifelse如何工作,如许多R函数,在每个元素上矢量。

答案 1 :(得分:1)

这是一种使用sign()并为所需值的矢量编制索引的方法:

t <- data.frame(a=1:5,b=5:1);
t;
##   a b
## 1 1 5
## 2 2 4
## 3 3 3
## 4 4 2
## 5 5 1
t$c <- c(1,2,0)[sign(t$a-t$b)+2];
t;
##   a b c
## 1 1 5 1
## 2 2 4 1
## 3 3 3 2
## 4 4 2 0
## 5 5 1 0

此处的优势在于您可以在以后轻松更改所需的值,因为它们已在索引向量中明确定义为( a<b {{1 }} a==b 的)。 Spacedman使用逻辑运算的解决方案非常出色(来自我的+1!),但不容易适应未来的价值变化。

答案 2 :(得分:0)

使用嵌套的ifelse

t$c=ifelse(t$a<t$b,1,

ifelse(t$a>t$b,0,2)

)

来自嵌套ifelse的帮助

?ifelse

类&#39; db.obj&#39;:

的S4方法

ifelse((测试,是,否))

参数 测试 db.obj对象,只有一列。该列可以转换为布尔值。 是 正常值或db.obj对象。当test为TRUE时,它是返回的值。 没有 测试为FALSE时返回的值。