【问题标题】:count multiple categories of a variable from a column and report them by creating new columns从列中计算变量的多个类别并通过创建新列来报告它们
【发布时间】:2020-01-15 23:02:28
【问题描述】:

假设我有两个列的数据(df)。其中一部分在下面给出。

  familyGroup Sex
 1    601       2
 2    601       1
 3    601       2
 4    601       1
 5    601       1
 6    601       2
 7    602       2
 8    602       1
 9    602       2
10    602       1
11    602       1
12    602       1

在性别栏和下。 我想要一个家庭组的男性和女性计数总和,并在两个新列中报告(比如在男性和女性下)

我正在使用来自tidyverse 包的dplyrgroup_bysummarymutate做了一些试验

我使用dplyr 尝试了以下代码。 但是输出并不像预期的那样。

df %>%
  group_by(familyGroup, Sex) %>%
  summarise(male = sum(Sex==1), female = sum(Sex == 2)) %>%
  select(familyGroup, male, female)
# A tibble: 74 x 3
# Groups:   familyGroup [40]
  familyGroup  male female
   <fct>       <int>  <int>
 1     601      3      0
 2     601      0      3
 3     602      4      0
 4     602      0      2

预期的输出如下所示

familyGroup   male  female
        601    3     3
        602    4     2

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    看起来这确实是基本函数的一个很好的用例。

    df <- data.frame("familyGroup" = c(rep(601, 6), rep(602, 6)),
                     "Sex" = c(2,1,2,1,1,2,2,1,2,1,1,1))
    df$Sex <- ifelse(df$Sex == 1, "Male", "Female")
    table(df$familyGroup, df$Sex)
    
          Female Male
      601      3    3
      602      2    4
    

    如果您想要更复杂的表格,ftable()xtabs() 都非常有用。

    【讨论】:

      【解决方案2】:

      您可以使用来自data.table 包的dcast 执行此操作,如下所示:

      library(data.table)
      library(dplyr)
      dt <- read.table(text = " familyGroup Sex
       1    601       2
       2    601       1
       3    601       2
       4    601       1
       5    601       1
       6    601       2
       7    602       2
       8    602       1
       9    602       2
      10    602       1
      11    602       1
      12    602       1")
      
      dt <- data.table(dt)
      
      dt[, 
          sexLabel := dplyr::case_when(
            Sex == 1 ~ "male",
            Sex == 2 ~ "female",
            TRUE ~ "(unknown)"
          )
      ]
      
      res <- dcast(
        formula = familyGroup ~ sexLabel,  
        data = dt, 
        fun.aggregate = length,
        value.var = "Sex"
      )
      res
      #       familyGroup female male
      # 1:         601      3    3
      # 2:         602      2    4
      

      【讨论】:

        【解决方案3】:

        我们可以 countfamilyGroupSex 值。将 1 更改为 "male" 并将 2 更改为 "female"spread 将其更改为宽格式。

        library(dplyr)
        
        df %>% 
          count(familyGroup, Sex) %>%
          mutate(Sex = ifelse(Sex == 1, "male", "female")) %>%
          tidyr::spread(Sex, n)
        
        #  familyGroup female  male
        #        <int>  <int> <int>
        #1         601      3     3
        #2         602      2     4
        

        【讨论】:

        • 非常感谢罗纳克!这是所需的输出。
        • 如果存在三个变量(比如男性、女性和变性人),我是否应该扩展 语句以包含它。
        • @manoj1123 是的,将 1 更改为“男性”并将 2 更改为“女性”的原因是要有有意义的列名。否则 df %&gt;% count(familyGroup, Sex) %&gt;% tidyr::spread(Sex, n) 也可以。
        猜你喜欢
        • 1970-01-01
        • 2017-11-03
        • 1970-01-01
        • 2015-08-17
        • 1970-01-01
        • 2018-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多