报告data.frame中缺失值的优雅方法

报告data.frame中缺失值的优雅方法,r,dataframe,missing-data,R,Dataframe,Missing Data,下面是我编写的一段代码,用于报告数据帧中缺少值的变量。我试图想出一种更优雅的方法来实现这一点,一种可能返回data.frame的方法,但我被卡住了: for (Var in names(airquality)) { missing <- sum(is.na(airquality[,Var])) if (missing > 0) { print(c(Var,missing)) } } for(名称中的变量(空气质量)){ 缺少(0){ 打印(c

下面是我编写的一段代码,用于报告数据帧中缺少值的变量。我试图想出一种更优雅的方法来实现这一点,一种可能返回data.frame的方法,但我被卡住了:

for (Var in names(airquality)) {
    missing <- sum(is.na(airquality[,Var]))
    if (missing > 0) {
        print(c(Var,missing))
    }
}
for(名称中的变量(空气质量)){
缺少(0){
打印(c(变量,缺失))
}
}

编辑:我处理的是包含数十到数百个变量的data.Frame,所以关键是我们只报告缺少值的变量。

只需使用
sapply

> sapply(airquality, function(x) sum(is.na(x)))
  Ozone Solar.R    Wind    Temp   Month     Day 
     37       7       0       0       0       0
您还可以对由
is.na()创建的矩阵使用
apply
colSums


如果您想对特定列执行此操作,那么也可以使用

length(which(is.na(airquality[1])==T))
更简洁-:
sum(is.na(x[1])

就是

  • x[1]
    查看第一列

  • is.na()
    true,如果它是
    na

  • sum()
    TRUE
    1
    FALSE
    0

  • 已经给了你这个信息

    VIM包还为data.frame提供了一些很好的缺失数据图

    library("VIM")
    aggr(airquality)
    

    我们可以将
    map\u df
    与purrr一起使用

    库(鼠标)
    图书馆(purrr)
    #带有purrr的映射图
    map_df(空气质量,函数(x)和(is.na(x)))
    #一个tibble:1×6
    #臭氧太阳能.R风温月日
    #        
    # 1    37       7     0     0     0     0
    
    另一个可以帮助您查看缺失数据的函数是funModeling library中的df_status

    library(funModeling)
    
    iris.2是添加了一些NAs的iris数据集。您可以将其替换为数据集

    df_status(iris.2)
    

    这将为您提供每列中NAs的数量和百分比。

    我认为Amelia库在处理缺失数据方面做得很好,还包括一个用于可视化缺失行的映射

    install.packages("Amelia")
    library(Amelia)
    missmap(airquality)
    

    您还可以运行以下代码将返回na的逻辑值

    row.has.na <- apply(training, 1, function(x){any(is.na(x))})
    

    row.has.na对于另一个图形解决方案,
    visdat
    提供了
    visu miss

    library(visdat)
    vis_miss(airquality)
    


    与Amelia
    输出非常相似,只是有一点差异,即在未命中时给出%s

    另一个图形替代方案-
    plot\u缺少优秀的
    DataExplorer
    软件包中的功能:

    还指出了一个事实,即您可以使用
    missing_data保存此结果以进行额外分析。我最喜欢的数据(不太广泛)是来自优秀软件包的方法。您不仅可以获得频率,还可以获得丢失的模式:

    library(naniar)
    library(UpSetR)
    
    riskfactors %>%
      as_shadow_upset() %>%
      upset()
    

    查看缺失与非缺失的关系通常很有用,这可以通过绘制缺失散点图来实现:

    ggplot(airquality,
           aes(x = Ozone,
               y = Solar.R)) +
     geom_miss_point()
    

    或对于分类变量:

    gg_miss_fct(x = riskfactors, fct = marital)
    


    这些示例来自列出其他有趣可视化的包

    另一种图形化和交互式方式是使用
    is.na10
    函数,该函数来自
    heatmaply
    库:

    library(heatmaply)
    
    heatmaply(is.na10(airquality), grid_gap = 1, 
              showticklabels = c(T,F),
                k_col =3, k_row = 3,
                margins = c(55, 30), 
                colors = c("grey80", "grey20"))
    


    可能无法很好地处理大型数据集。

    ExPanDaR的软件包功能可用于浏览面板数据:


    A
    dplyr
    获取计数的解决方案可以是:

    summarise_all(df, ~sum(is.na(.)))
    
    或者获得一个百分比:

    summarise_all(df, ~(sum(is_missing(.) / nrow(df))))
    
    也许还值得注意的是,丢失的数据可能是丑陋的、不一致的,并且不总是编码为
    NA
    ,具体取决于源代码或导入时的处理方式。下面的函数可以根据您的数据和您想考虑的缺失来调整:

    is_missing <- function(x){
      missing_strs <- c('', 'null', 'na', 'nan', 'inf', '-inf', '-9', 'unknown', 'missing')
      ifelse((is.na(x) | is.nan(x) | is.infinite(x)), TRUE,
             ifelse(trimws(tolower(x)) %in% missing_strs, TRUE, FALSE))
    }
    
    # sample ugly data
    df <- data.frame(a = c(NA, '1', '  ', 'missing'),
                     b = c(0, 2, NaN, 4),
                     c = c('NA', 'b', '-9', 'null'),
                     d = 1:4,
                     e = c(1, Inf, -Inf, 0))
    
    # counts:
    > summarise_all(df, ~sum(is_missing(.)))
      a b c d e
    1 3 1 3 0 2
    
    # percentage:
    > summarise_all(df, ~(sum(is_missing(.) / nrow(df))))
         a    b    c d   e
    1 0.75 0.25 0.75 0 0.5
    


    is_missing@kohske:这是我的第一个想法,但是结果是一个字符的
    ,你必须解析出NAs的数量。我回复你的问题,因为你发布了答案。如果您想对答案发表评论,请作为对该答案的评论。如果问题中还包含答案,这将变得非常混乱。@Andrie:我不同意您的编辑,因为我面临的一个关键问题是只报告缺少值的变量。此外,您的回滚删除了我对代码所做的更改。我已经编辑了我的问题以包含这些信息,并将我修改过的Josh代码添加到注释中。@Zach我觉得你的新编辑很好。我并不反对在问题上线后添加额外的数据/请求,顺便说一句,如果这能澄清问题的话。有50万种方法可以做到这一点,请看我稍微修改了您的代码,只报告缺少的值:
    m 0]
    谢谢!学到了很多。嗨@Joshua Ulrich,非常感谢你简洁的代码。我想在数据框中添加一列,显示na值的百分比。您能提供一些帮助吗?@Zach我使用您建议的一个版本来检查必填字段是否有值:
    M@Joshua为%s添加一个选项也是ace!您不需要将逻辑向量与t进行比较。您还可以通过求和来计算逻辑向量中的真元素数。这并没有回答最初的问题,即查找数据中所有列的
    NA
    s的数量。VIM包是否可以报告哪些特定观察缺少数据?不要这样认为。。但是你可以很容易地做到这一点(你必须用你自己的数据帧替换空气质量):res0,]与sapply相比,
    map\u df
    有什么优势?@Zach我认为没有什么大的区别,但是Hadley说不要在函数中使用sapply()。请参阅异常和调试·高级R
    @Zach
    map\u-df
    优于
    sapply
    的优点仅当结果有多行时,因为map\u-df的输出格式总是一个tible。@Zach:最好在函数中使用
    vapply
    vs
    sapply
    ,因为
    vapply
    提供了一个已知的结果结构(由您指定).
    sapply
    可以返回数组或列表
    summarise_all(df, ~(sum(is_missing(.) / nrow(df))))
    
    is_missing <- function(x){
      missing_strs <- c('', 'null', 'na', 'nan', 'inf', '-inf', '-9', 'unknown', 'missing')
      ifelse((is.na(x) | is.nan(x) | is.infinite(x)), TRUE,
             ifelse(trimws(tolower(x)) %in% missing_strs, TRUE, FALSE))
    }
    
    # sample ugly data
    df <- data.frame(a = c(NA, '1', '  ', 'missing'),
                     b = c(0, 2, NaN, 4),
                     c = c('NA', 'b', '-9', 'null'),
                     d = 1:4,
                     e = c(1, Inf, -Inf, 0))
    
    # counts:
    > summarise_all(df, ~sum(is_missing(.)))
      a b c d e
    1 3 1 3 0 2
    
    # percentage:
    > summarise_all(df, ~(sum(is_missing(.) / nrow(df))))
         a    b    c d   e
    1 0.75 0.25 0.75 0 0.5