【问题标题】:How to summarise across different types of variables with dplyr::c_across()如何使用 dplyr::c_across() 总结不同类型的变量
【发布时间】:2020-09-18 17:09:08
【问题描述】:

我有不同类型变量的数据。有些是字符,有些是因数,有些是数字,如下所示:

df <- data.frame(a = c("tt", "ss", "ss", NA), b=c(2,3,NA,1), c=c(1,2,NA, NA), d=c("tt", "ss", "ss", NA))

我正在尝试使用c_across in dplyr 计算每次观察的缺失值数量 但是,c_across 似乎无法组合不同类型的值,如下面的错误消息所示

df %>%
  rowwise() %>%
  summarise(NAs = sum(is.na(c_across())))

错误:summarise() 输入 NAs 有问题。 x 不能组合 a b 。 ℹ 输入NAssum(is.na(c_across()))。 ℹ 错误发生在第 1 行。

确实,如果我只包含数字变量,它就可以工作。

df %>%
  rowwise() %>%
  summarise(NAs = sum(is.na(c_across(b:c))))

如果我只包含字符变量也是一样

df %>%
  rowwise() %>%
  summarise(NAs = sum(is.na(c_across(c(a,d)))))

我可以不使用c_across 来解决这个问题,但我有很多变量,所以不太实用。

df %>%
  rowwise() %>%
  summarise(NAs = is.na(a)+is.na(b)+is.na(c)+is.na(d))

我可以使用传统的apply 方法,如下所示,但我想使用dplyr 来解决这个问题。

apply(df, 1, function(x)sum(is.na(x)))

关于如何计算缺失值的数量、逐行、高效和使用dplyr,有什么建议吗?

【问题讨论】:

    标签: r dplyr rowwise


    【解决方案1】:

    我会建议这种方法。问题是因为两件事。首先,数据框中的变量类型不同,其次是行式任务需要一个关键变量。因此,在接下来的代码中,我们首先将变量转换为类似的类型,然后根据行数创建一个 id。有了这个,我们使用该元素作为rowwise() 的输入,然后我们可以使用c_across() 函数。这里是代码(我用过你df数据):

    library(tidyverse)
    #Code
    df %>% 
      mutate_at(vars(everything()),funs(as.character(.))) %>%
      mutate(id=1:n()) %>%
      rowwise(id) %>%
      mutate(NAs = sum(is.na(c_across(a:d))))
    

    输出:

    # A tibble: 4 x 6
    # Rowwise:  id
      a     b     c     d        id   NAs
      <chr> <chr> <chr> <chr> <int> <int>
    1 tt    2     1     tt        1     0
    2 ss    3     2     ss        2     0
    3 ss    NA    NA    ss        3     2
    4 NA    1     NA    NA        4     3
    

    我们可以避免mutate_at() 函数,使用新的across()mutate() 来认证变量:

    #Code 2
    df %>% 
      mutate(across(a:d,~as.character(.))) %>%
      mutate(id=1:n()) %>%
      rowwise(id) %>%
      mutate(NAs = sum(is.na(c_across(a:d))))
    

    输出:

    # A tibble: 4 x 6
    # Rowwise:  id
      a     b     c     d        id   NAs
      <chr> <chr> <chr> <chr> <int> <int>
    1 tt    2     1     tt        1     0
    2 ss    3     2     ss        2     0
    3 ss    NA    NA    ss        3     2
    4 NA    1     NA    NA        4     3
    

    【讨论】:

    • 第二个快一点。
    【解决方案2】:

    更快的选择不是使用rowwisec_across,而是使用rowSums

    library(dplyr)
    df %>% 
         mutate(NAs = rowSums(is.na(.)))
    #     a  b  c    d NAs
    #1   tt  2  1   tt   0
    #2   ss  3  2   ss   0
    #3   ss NA NA   ss   2
    #4 <NA>  1 NA <NA>   3
    

    如果我们想select某些列,即numeric

    df %>%
       mutate(NAs = rowSums(is.na(select(., where(is.numeric)))))
    #     a  b  c    d NAs
    #1   tt  2  1   tt   0
    #2   ss  3  2   ss   0
    #3   ss NA NA   ss   2
    #4 <NA>  1 NA <NA>   1
    

    【讨论】:

      猜你喜欢
      • 2020-08-24
      • 2018-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      • 2018-06-29
      • 2016-09-17
      相关资源
      最近更新 更多