【问题标题】:How to subset a data.frame if the column contains NAs [duplicate]如果列包含 NA,如何对 data.frame 进行子集化 [重复]
【发布时间】:2018-01-23 14:17:33
【问题描述】:

在基于字符列的条件对数据框进行子集化时,R(3.3.3 版)给了我一些意想不到的行为。这是一个例子:

foo <- data.frame(bar = c('a',NA,'b','a'),
                  baz = 1:4,
                  stringsAsFactors = FALSE)

foo 看起来像这样:

   bar baz
1    a   1
2 <NA>   2
3    b   3
4    a   4

我想得到这个数据框的所有行bar != "a",所以我打电话:

foo[foo$bar != 'a', ]

这会返回:

    bar baz
NA <NA>  NA
3     b   3

我不明白为什么第二列的第一个条目是NA 而不是2。请帮我解释一下这种奇怪的行为。

【问题讨论】:

  • 使用which:foo[which(foo$bar != 'a'), ]
  • @nicola 不幸的是,它也没有提供所需的行为,它只返回第 3 行(不返回 barNA 的行)。

标签: r dataframe


【解决方案1】:

虽然我试图理解这种行为,但在 R 中进行字符过滤的正确/更好的方法是使用 %in% 运算符。

foo <- data.frame(bar = c('a',NA,'b','a'),
                  baz = 1:4,
                  stringsAsFactors = FALSE)

foo[!(foo$bar %in% 'a'), ]

输出:

> foo[!(foo$bar %in% 'a'), ]
   bar baz
2 <NA>   2
3    b   3

更新:

这种行为不是因为字符过滤器。其实是因为NA是用来索引dataframe的。

> foo[c(F,NA,T,F),]
    bar baz
NA <NA>  NA
3     b   3

NA 作为索引值传递会将该位置的任何值替换为仅NA

> foo[NA,]
      bar baz
NA   <NA>  NA
NA.1 <NA>  NA
NA.2 <NA>  NA
NA.3 <NA>  NA
> foo[c(T,NA),]
      bar baz
1       a   1
NA   <NA>  NA
3       b   3
NA.1 <NA>  NA

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 2019-09-28
    • 2022-01-17
    相关资源
    最近更新 更多