首页 > 解决方案 > R功能建议

问题描述

我刚刚开始使用 R 并尝试编写一个函数,该函数可以通过数据中的列为我提供 NA 的摘要。我有一些问题:

  1. 如果我传递一个列表,该函数如何选择它的名称?例如,如果我通过“listA”,该函数应该返回 listA 和下面的 NA 的数量。目前,它返回“x”和下面的 NA 数。例如:

     E <- c(NA,1,2,3); na_cols_summary(E)
    

    产量

     $x
     [1] NA
    
  2. 有人可以建议,我如何使用“应用”系列的功能来使功能更优雅。

  3. 我们是否有具有类似功能的包/功能?

    ###Sample Data
    A <- c(1:10)
    B <- c(11:20)
    C <- c(21:30)
    D <- c(31:40)
    df <- data.frame(A, B, C, D)
    df <-
      as.data.frame(lapply(df, function(cc)
        cc[sample(
          c(TRUE, NA),
          prob = c(0.85, 0.15),
          size = length(cc),
          replace = TRUE
        )]))
    
    
    
    na_cols_summary <- function(x) {
       x <- as.data.frame(x)
       y <- colSums(is.na(x))
       y <- y[y != 0]
       nalis <- list()
       i <- 1
       for (z in names(y)) {
            nalis[i] <- list(x[is.na(x[, z]), ])
            i <- i + 1
        }
       names(nalis) <- names(y)
       return(nalis)
       }
    df_na <- na_cols_summary(df)
    
    df_na
    $A
       A  B  C  D
    3  NA NA 23 33
    4  NA 14 24 34
    10 NA 20 30 40
    
    $B
       A  B  C  D
    3 NA NA 23 33
    8  8 NA 28 38
    

标签: r

解决方案


您可以使用lapply.

这模仿了您的功能。

lapply(df2 <- df1[colSums(is.na(df1)) > 0], function(x) df2[is.na(x), ])
# $A
#    A  B  C
# 1 NA 11 NA
# 2 NA 12 22
# 
# $B
#   A  B  C
# 3 3 NA NA
# 6 6 NA 26
# 7 7 NA 27
# 
# $C
#    A  B  C
# 1 NA 11 NA
# 3  3 NA NA
# 4  4 14 NA
# 8  8 18 NA

不仅要让缺失的列进入输出,只需执行lapply(df1, function(x) df1[is.na(x), ]).

要获取对象的名称,您可以使用deparse(substitute(.))

f <- function(x) deparse(substitute(x))
f(E)
# [1] "E"

要将其组合成一个函数,您可以执行以下操作:

na_cols_summary2 <- function(x) {
  stopifnot(is.data.frame(x) | is.vector(x))
  if (!any(is.na(x))) {
    return(message("No missings found.\n"))
  }
  if (is.data.frame(x)) {
    res <- lapply(x, function(i) x[is.na(i), ])
    res <- res[lapply(res, nrow) > 0]
  } else {
    res <- setNames(as.data.frame(x), deparse(substitute(x)))
  } 
  return(res)
}

用法

na_cols_summary2(df1)
# $A
#    A  B  C  D
# 1 NA 11 NA 31
# 2 NA 12 22 32
# 
# $B
#   A  B  C  D
# 3 3 NA NA 33
# 6 6 NA 26 36
# 7 7 NA 27 37
# 
# $C
#    A  B  C  D
# 1 NA 11 NA 31
# 3  3 NA NA 33
# 4  4 14 NA 34
# 8  8 18 NA 38

na_cols_summary2(E)
#    E
# 1 NA
# 2  1
# 3  2
# 4  3

na_cols_summary2(E2)
# No missings found.

na_cols_summary2(matrix(0, 4))
# Error in na_cols_summary2(matrix(0, 4)) : 
#  is.data.frame(x) | is.vector(x) is not TRUE 

数据

df1 <- structure(list(A = c(NA, NA, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L), 
    B = c(11L, 12L, NA, 14L, 15L, NA, NA, 18L, 19L, 20L), C = c(NA, 
    22L, NA, NA, 25L, 26L, 27L, NA, 29L, 30L), D = c(31, 32, 
    33, 34, 35, 36, 37, 38, 39, 40)), row.names = c(NA, -10L), class = "data.frame")

E <- c(NA, 1, 2, 3)
E2 <- 1:4

推荐阅读