【问题标题】:transpose data.frame and counting non NA values per column转置 data.frame 并计算每列的非 NA 值
【发布时间】:2019-08-04 14:26:26
【问题描述】:

我有这个数据框:

set.seed(100)
x <- data.frame(KAS1_1 = sample(c(letters[1], NA), 10, replace =TRUE),
                KAS1_2 = sample(c(letters[2], NA), 10, replace =TRUE),
                KAS1_3 = sample(c(letters[3], NA), 10, replace =TRUE),
                KAS1_4 = sample(c(letters[4], NA), 10, replace =TRUE),
                KAS1_5 = sample(c(letters[5], NA), 10, replace =TRUE),
                stringsAsFactors = FALSE)
> df
   KAS1_1 KAS1_2 KAS1_3 KAS1_4 KAS1_5
1       a   <NA>   <NA>      d      e
2       a   <NA>   <NA>   <NA>   <NA>
3    <NA>      b   <NA>      d   <NA>
4       a      b   <NA>   <NA>   <NA>
5       a   <NA>      c   <NA>   <NA>
6       a   <NA>      c   <NA>      e
7    <NA>      b   <NA>      d   <NA>
8       a      b   <NA>   <NA>   <NA>
9    <NA>      b   <NA>   <NA>      e
10      a   <NA>      c      d      e

我正在寻找一种方法来获得这个:

   Var   Count
KAS1_1   8
KAS1_2   5
KAS1_3   3
KAS1_4   4
KAS1_5   4

我正在尝试使用dplyrtablelapply()t(),但没有结果。有没有更直接的方法?

【问题讨论】:

  • 以后我建议展示你的一些尝试。如果我们发现您的方法出了什么问题,我们可以帮助您了解更多信息。

标签: r dplyr lapply data-manipulation


【解决方案1】:
## halfway there
colSums(!is.na(x))
# KAS1_1 KAS1_2 KAS1_3 KAS1_4 KAS1_5 
#      7      5      3      4      4 

## make it a data frame
data.frame(count = colSums(!is.na(x)))
#        count
# KAS1_1     7
# KAS1_2     5
# KAS1_3     3
# KAS1_4     4
# KAS1_5     4

## or use `stack` like markus's nice answer:
stack(colSums(!is.na(x)))
#   values    ind
# 1      7 KAS1_1
# 2      5 KAS1_2
# 3      3 KAS1_3
# 4      4 KAS1_4
# 5      4 KAS1_5

将行名转换为它们自己的列将是另一个步骤,但我将把它留给你。

tidyverse 解决方案将让您转换为长格式,然后进行分组求和:

library(dplyr)
library(tidyr)
x %>% gather %>%
  group_by(key) %>%
  summarize(value = sum(!is.na(value)))
# # A tibble: 5 x 2
#   key    value
#   <chr>  <int>
# 1 KAS1_1     7
# 2 KAS1_2     5
# 3 KAS1_3     3
# 4 KAS1_4     4
# 5 KAS1_5     4

data.table 解决方案类似:

library(data.table)
xdt = as.data.table(x)
melt(xdt, measure.vars = names(xdt))[, .(count = sum(!is.na(value))), by = .(variable)]
#    variable count
# 1:   KAS1_1     7
# 2:   KAS1_2     5
# 3:   KAS1_3     3
# 4:   KAS1_4     4
# 5:   KAS1_5     4

【讨论】:

    【解决方案2】:

    基础 R 选项

    stack(lapply(x, function(y) length(na.omit(y))))
    #  values    ind
    #1      7 KAS1_1
    #2      5 KAS1_2
    #3      3 KAS1_3
    #4      4 KAS1_4
    #5      4 KAS1_5
    

    Gregor 的解决方案之外的另一个tidyverse 选项是

    library(dplyr); library(tidyr)
    gather(x, na.rm = TRUE) %>% count(key)
    

    【讨论】:

      猜你喜欢
      • 2016-01-08
      • 2022-12-20
      • 2022-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 1970-01-01
      相关资源
      最近更新 更多