子集使用`[`,解释NA输出

时间:2013-02-06 21:21:38

标签: r

如果我们有他的数据recentely used here

data <- data.frame(name = rep(letters[1:3], each = 3), 
                   var1 = rep(1:9), var2 = rep(3:5, each = 3))

  name var1 var2
1    a    1    3
2    a    2    3
3    a    3    3
4    b    4    4
5    b    5    4
6    b    6    4
7    c    7    5
8    c    8    5
9    c    9    5

我们可以查找var2 == 4的行。

data[data[,3] == 4 ,] # equally data[data$var2 == 4 ,]

#  name var1 var2
#4    b    4    4
#5    b    5    4
#6    b    6    4

或var1和var2 == 4

的行
data[data[,2] == 4 &  data[,3] == 4,]

#  name var1 var2
#4    b    4    4

我没有得到的是为什么:

data[ data[ , 2:3 ] == 4 ,]

给出了这个:

     name var1 var2
4       b    4    4
NA   <NA>   NA   NA
NA.1 <NA>   NA   NA
NA.2 <NA>   NA   NA

#I would still hope to get 
 #  name var1 var2
#4    b    4    4

NAs来自哪里?

4 个答案:

答案 0 :(得分:3)

您正在进行子集化的逻辑是矩阵:

> sel <- data[ , 2:3 ] == 4
> sel
       var1  var2
 [1,] FALSE FALSE
 [2,] FALSE FALSE
 [3,] FALSE FALSE
 [4,]  TRUE  TRUE
 [5,] FALSE  TRUE
 [6,] FALSE  TRUE
 [7,] FALSE FALSE
 [8,] FALSE FALSE
 [9,] FALSE FALSE

根据help("[.data.frame")

  

矩阵索引(x [i]具有逻辑或2列整数矩阵i)   使用[不推荐,几乎不支持。对于提取,x是   首先强迫一个矩阵。替换,逻辑矩阵(仅)   可用于以相同的方式选择要替换的元素   对于矩阵。

但这意味着这种形式:

> data[ sel ]
[1] "b" "4" "5" "6" "4"

不良。你正在做的事情甚至不那么敏感,因为你告诉它你只想要行(用你的尾随逗号),然后给它一个矩阵来索引!

> data[sel,]
     name var1 var2
4       b    4    4
NA   <NA>   NA   NA
NA.1 <NA>   NA   NA
NA.2 <NA>   NA   NA

如果您真的想使用矩阵表单,可以使用apply跨行应用逻辑运算。

答案 1 :(得分:2)

您的data[,2:3]==4如下:

R> data[,2:3]==4
       var1  var2
 [1,] FALSE FALSE
 [2,] FALSE FALSE
 [3,] FALSE FALSE
 [4,]  TRUE  TRUE
 [5,] FALSE  TRUE
 [6,] FALSE  TRUE
 [7,] FALSE FALSE
 [8,] FALSE FALSE
 [9,] FALSE FALSE

然后尝试使用此矩阵索引数据框的行。为此,R似乎首先将矩阵转换为向量:

R> as.vector(data[,2:3]==4)
 [1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[12] FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE

然后根据此向量选择data行。第4个TRUE值选择第4行,但其他三个TRUE值选择“越界”行,因此返回NA

答案 2 :(得分:0)

    data[ data[ , 2 ] == 4 | data[,3] == 4,]

    name  var1 var2
 4    b    4    4
 5    b    5    4
 6    b    6    4

我怀疑你的方法不起作用,因为c()构建了一个向量,而你需要比较原子元素。

答案 3 :(得分:0)

因为您没有将矢量传递给索引而是传递矩阵:

> data[ , 2:3 ] == 4
       var1  var2
 [1,] FALSE FALSE
 [2,] FALSE FALSE
 [3,] FALSE FALSE
 [4,]  TRUE  TRUE
 [5,] FALSE  TRUE
 [6,] FALSE  TRUE
 [7,] FALSE FALSE
 [8,] FALSE FALSE
 [9,] FALSE FALSE

如果您希望将矩阵折叠为矢量,则索引与此处一起使用有两个选项:

data[ apply(data[ , 2:3 ] == 4, 1, all) ,]
data[ rowSums(data[ , 2:3 ] == 4) == 2 ,]