在列表上应用函数,无法从每个元素的名称中提取所需的部分

时间:2018-03-12 20:09:06

标签: r

我写了以下函数:

require(data.table)
missing.na <- function(x) {
  table <- table(x, useNA = "always")
  df.table <- as.data.frame(table)
  data.frame <- data.frame("Present" = c(gsub("^.*\\$", "", deparse(substitute(x))), "Present", sum(subset(df.table, !is.na(df.table[, 1]))[, 2])), 
                           "Missing" = c(NA, "Missing", sum(subset(df.table, is.na(df.table[, 1]))[, 2])))
  return(data.frame)
}

我需要在以下数据框中应用某些向量并将输出组合成新的数据框(示例数据):

df <- data.frame("s1" = c("1", "2", "3", NA, NA, NA), "s1a" = c(NA, "3", NA, "5", "6", "5"), "s1b" = c("2", "2", "3", "2", "2", "2"))

以下作品:

Output1 <- rbindlist(list(missing.na(df$s1), missing.na(df$s1a), missing.na(df$s1b)))

我在&#39; $&#39;之后得到了矢量的名称。运算符返回它应该的位置(每3行,第一列)。

然而,我知道我应该能够通过在向量列表上应用函数来简化这一点(实际项目有更多不同长度的向量)。但是,当我尝试:

Varlist <- list(df$s1, df$s1a, df$s1b)
Output2 <- rbindlist(lapply(Varlist, missing.na))

我得到了X [[i]]&#39;而不是我想要的每个向量的名称的一部分。如何在我的矢量列表中应用我的函数,并在&#39; Output2&#39;中获得相同的输出。我进入&#39;输出1&#39;?

1 个答案:

答案 0 :(得分:0)

我认为你可以通过几个tidyverse函数(来自tibble和purrr来完成你的工作。首先,我将你的函数改为接受一个名字参数,而不是要求一个deparse

missing.na <- function(x, name=deparse(substute(x))) {
  table <- table(x, useNA = "always")
  df.table <- as.data.frame(table)
  data.frame <- data_frame("Present"=c(gsub("^.*\\$", "", name), "Present", sum(subset(df.table, !is.na(df.table[, 1]))[, 2])), 
                           "Missing"=c(NA, "Missing", sum(subset(df.table, is.na(df.table[, 1]))[, 2])))
  return(data.frame)
}

然后您可以使用lst()为您创建一个命名列表,并将其传递给map2_dfr()以使用两个参数调用您的函数并将其收集到data.frame

tibble::lst(df$s1, df$s1a, df$s1b) %>% 
    purrr::map2_dfr(., names(.), missing.na)

This returns

  Present Missing
    <chr>   <chr>
1      s1    <NA>
2 Present Missing
3       3       3
4     s1a    <NA>
5 Present Missing
6       4       2
7     s1b    <NA>
8 Present Missing
9       6       0