如何让ifelse()抛出数据帧?

时间:2018-03-11 17:43:28

标签: r if-statement

为什么这些ifelse()不会抛出数据帧(或矩阵)?

x <- data.frame(a=1000, b=100)
> x
     a   b
1 1000 100

> ifelse(x[, 2] >= 8, x, NA)
[[1]]
[1] 1000

> ifelse(x[, 2] >= 8, x[1:2], NA)
[[1]]
[1] 1000

> ifelse(x[, 2] >= 8, cbind(x[[1]], x[[2]]), NA)
[1] 1000

第二列总是丢失。如何做到这一点?

2 个答案:

答案 0 :(得分:4)

从其帮助文件:

  

ifelse返回一个值与test 形状相同的值   选择是或否的元素取决于是否   测试元素为TRUE或FALSE。

因此,如果输入是数据帧,它实际上会返回数据帧:

ifelse(x[, 1, drop = FALSE] > 0, 10, NA)

但在你的情况下,它更容易使用

if (test) x else NA

答案 1 :(得分:3)

以下有关ifelse返回值的引用行非常重要(取自help),以便了解ifelse的行为

  

     

具有相同长度和属性的矢量(包括尺寸和尺寸)   “class”)作为来自yes或no的值的测试和数据值。

     

详情

     

如果是或否太短,其元素将被回收。

总之,它建议对于,对于测试部分中的每个rowcolumn将返回相应数据值的值。

让我们举几个例子来理解它。

x <- data.frame(a=1000, b=100)


ifelse(x[, 2] >= 8, x, NA)
# Test : 1 row and 1 col. Hence return is x[1]
# [[1]]
#[1] 1000

ifelse(x[, 2] >= 8, x[,2], NA)
# Test : 1 row and 1 col. Hence return is x[,2][1]
#[1] 100

ifelse(x >= 8, x, NA)
# Test : 1 row and 2 cols. Hence return is x[1,1] and x[1,1]
# [[1]]
# [1] 1000
# 
# [[2]]
# [1] 100

ifelse(x >= 8, 4, NA)
# Test : 1 row and 2 cols. Values are recycled. 4 & 4 for corresponding row/col
#    a b
#[1,] 4 4 

#Change x to 2x2
x <- data.frame(a=1000:1001, b=100:101)
ifelse(x >= 8, 4, NA)
# Test : 2 row and 2 cols. Result will be 2 x 2 
#     a b
#[1,] 4 4
#[2,] 4 4

现在,有什么选择可以解决这个问题?

当然可以按照@Jordi的建议使用if。但要小心if没有矢量化。因此,当在测试条件中使用1st时,测试条件仅应用于vector元素。为了处理这些情况,anyall等函数非常方便,可以在vector中使用if作为测试条件的一部分。