【问题标题】:Subset of rows containing NA (missing) values in a chosen column of a data frame在数据框的选定列中包含 NA(缺失)值的行子集
【发布时间】:2026-02-01 02:20:07
【问题描述】:

我们有一个来自 CSV 文件的数据框。数据框DF 具有包含观察值的列和包含进行测量的日期的列 (VaR2)。如果未记录日期,则 CSV 文件包含值 NA,表示缺失数据。

Var1  Var2 
10    2010/01/01
20    NA
30    2010/03/01

我们想使用子集命令来定义一个新的数据框new_DF,这样它就只包含列中具有NA' 值的行(VaR2)。在给出的示例中,只有第 2 行将包含在新的 DF 中。

命令

new_DF<-subset(DF, DF$Var2=="NA") 

不起作用,生成的数据框没有行条目。

如果在原始 CSV 文件中将值 NANULL 交换,则相同的命令会产生所需的结果:

new_DF <- subset(DF, DF$Var2=="NULL")

如果原始 CSV 文件中为字符串提供了值 NA,我如何才能使此方法起作用?

【问题讨论】:

    标签: r csv dataframe subset na


    【解决方案1】:

    切勿使用 =='NA' 来测试缺失值。请改用is.na()。应该这样做:

    new_DF <- DF[rowSums(is.na(DF)) > 0,]
    

    或者如果您想检查特定列,也可以使用

    new_DF <- DF[is.na(DF$Var),]
    

    如果您有 NA 字符值,请先运行

    Df[Df=='NA'] <- NA
    

    用缺失值替换它们。

    【讨论】:

    • 感谢您的快速回答(这很快)!事实上,由于数据的 csv 传递,“NA”是字符值,您的第二个语句可能非常有用。你能澄清你的第一个陈述吗?我不清楚 rowSums() 的使用,因为我只会检查一个特定的列(有很多列)。如果该特定列(在示例中为 Var2 列)有一个“NA”字符串(我将用您的第二条语句替换它),那么我想选择整行作为新数据框的一部分.
    • @John:已更新。重点是使用is.na,我错误地解释了你想检查所有变量。
    • 应该是new_DF &lt;- DF[is.na(DF$Var),],即DF[之后似乎有一个额外的(括号?
    【解决方案2】:

    当一行中的所有值都不是NA时,complete.cases 给出TRUE

    DF[!complete.cases(DF), ]
    

    【讨论】:

      【解决方案3】:

      NA 是 R 中的一个特殊值,不要将 NA 值与“NA”字符串混淆。根据导入数据的方式,您的“NA”和“NULL”单元格可能是各种类型(默认行为是将“NA”字符串转换为 NA 值,并让“NULL”字符串保持原样)。

      如果使用 read.table() 或 read.csv(),您应该考虑使用“na.strings”参数进行干净的数据导入,并始终使用真实的 R NA 值。

      一个例子,在“NULL”和“NA”单元格两种情况下工作:

      DF <- read.csv("file.csv", na.strings=c("NA", "NULL"))
      new_DF <- subset(DF, is.na(DF$Var2))
      

      【讨论】:

      • 感谢您的回答。如果我理解正确,第一个语句将与 Joris 示例中的 Df[Df=='NA']
      • 没错。 Joris 建议手动将“NA”字符串替换为 NA 值,这里我只建议使用 read.table() 的“na.strings”功能来达到相同的目的。
      • Joris 的回答实际上是完成这一壮举的“首选”方式(如果您在脚本中编写此代码)。见:*.com/questions/9860090/…
      • @Jonathan :这里有两个不同的想法,你引用的主题说“[”应该在“子集”上首选,但我们在 read.table() 中讨论了“na.strings”参数,我的子集只是为了可视化效果。
      【解决方案4】:
      new_data <- data %>% filter_all(any_vars(is.na(.))) 
      

      这应该会创建一个新的数据框 (new_data),其中只有缺失的值。

      最好跟踪您以后可能删除的值,因为它们有一些缺少观察值 (NA) 的列。

      【讨论】:

        【解决方案5】:

        尝试改变这个:

        new_DF<-dplyr::filter(DF,is.na(Var2)) 
        

        【讨论】:

        • 你能解释一下为什么这样有效吗?这是做什么的等等?
        • new_DF
        • DF %&gt;% filter(is.na(Var2))library(dplyr) 之后更好地表达。
        【解决方案6】:

        由于dplyrs filter_all 已被取代

        作用域动词(_if、_at、_all)已被现有动词中across() 的使用所取代。

        并且across()filter() 中的使用已被弃用,Ronak Pol's answer 需要一个小的更新。要在任何地方查找所有带有NA 的行,我们可以使用

        library(dplyr)
        
        DF %>% 
          filter(if_any(everything(), is.na))
        

        得到

        # A tibble: 1 x 2
           Var1 Var2  
          <dbl> <date>
        1    20 NA   
        

        【讨论】:

          【解决方案7】:

          打印所有包含 NA 数据的行:

          tmp <- data.frame(c(1,2,3),c(4,NA,5));
          tmp[round(which(is.na(tmp))/ncol(tmp)),]
          

          【讨论】:

          • @ZheyuanLi 如果您不喜欢这个答案,只需投反对票即可。编辑建议标记的答案不是适当的操作。如果您觉得有必要,请发表评论。
          最近更新 更多