【问题标题】:Calculate value from an existent column based on condition with dplyr使用 dplyr 根据条件计算现有列的值
【发布时间】:2020-07-04 11:50:08
【问题描述】:

我有一个包含“性别”和“经济”列的数据集,其中包含以下观察结果:

  gender  economy
1    Male      Bad
2  Female      Bad
3  Female      Bad
4    Male      Bad
5    Male     Good
6    Male      Bad
7    Male Very bad
8    Male Very bad
9    Male Very bad
10   Male Very bad
11 Female      Bad
12   Male     Good
13   Male     Good
14 Female     Good
15   Male      Bad
16 Female     Good
17 Female Very bad
18   Male Very bad
19 Female     Good
20 Female      Bad

structure(list(gender = structure(c(2L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 1L, 2L, 2L, 1L, 2L, 1L, 1L, 2L, 1L, 1L), .Label = c("Female", 
"Male"), class = "factor"), economy = structure(c(3L, 3L, 3L, 
3L, 2L, 3L, 4L, 4L, 4L, 4L, 3L, 2L, 2L, 2L, 3L, 2L, 4L, 4L, 2L, 
3L), .Label = c("Very good", "Good", "Bad", "Very bad", "Don't know"
), class = "factor")), row.names = c(NA, 20L), class = "data.frame")

我现在想计算女性和男性的比例,以及受访者表示经济不好或非常糟糕的总和值。我可以在 R 之外手动计算它,但我想知道在 R 中快速计算它的方法。我知道如何计算份额,但现在我被困住了:

lebanon %>%
  group_by(gender) %>%
  filter(!is.na(economy), economy != "Don't know") %>%
  count(economy) %>%
  mutate(prop = n / sum(n) * 100)

  gender economy       n   prop
  <fct>  <fct>     <int>  <dbl>
1 Female Very good     7  0.586
2 Female Good        146 12.2  
3 Female Bad         544 45.6  
4 Female Very bad    497 41.6  
5 Male   Very good     5  0.417
6 Male   Good        161 13.4  
7 Male   Bad         515 42.9  
8 Male   Very bad    519 43.2

问候

【问题讨论】:

  • 认为经济不景气或非常糟糕的受访者百分比将由100 * length(grep("B|bad", lebanon$economy))/nrow(lebanon) 给出
  • 很好,谢谢!有没有另一种方法可以让我得到每个性别的结果,就像我在这里发布的表格中一样?所以我有四行,每种性别两行,总和值为“非常好/好”和“非常坏/坏”。这将使它更容易与 ggplot 一起使用。
  • 嗨 Nicosc - 是的。我添加了一个答案

标签: r dplyr


【解决方案1】:

从您的初始 lebanon 数据框(我能够使用 uncount 从您的汇总表中恢复)开始,并尝试使用此代码,它使用 forcats::fct_collapse 组合所需的因子水平。

为了完整起见,我在末尾添加了一个简单的 ggplot。

library(forcats)
library(dplyr)
library(tidyr)
library(ggplot2)

df <- lebanon %>%
  group_by(gender) %>%
  filter(!is.na(economy), economy != "Don't know") %>%
  mutate(economy = fct_collapse(economy,
                   `Bad or very bad` = c("Bad", "Very bad"),
                   `Good or very good` = c("Good", "Very good"))
         ) %>%
  count(economy) %>%
  mutate(prop = n / sum(n) * 100)
           
df
#> # A tibble: 4 x 4
#> # Groups:   gender [2]
#>   gender economy               n  prop
#>   <fct>  <fct>             <int> <dbl>
#> 1 Female Bad or very bad    1041  87.2
#> 2 Female Good or very good   153  12.8
#> 3 Male   Bad or very bad    1034  86.2
#> 4 Male   Good or very good   166  13.8

ggplot(df, aes(x = gender, y = prop, fill = economy)) + 
  geom_col(position = "dodge", color = "black") +
  scale_fill_manual(values = c("red3", "forestgreen")) +
  labs(title = "Opinion on economy by gender", y = "Percentage of those polled")

【讨论】:

    【解决方案2】:

    这可能会有所帮助:

    library(dplyr)
    
    lebanon %>%
      mutate(type = ifelse(grepl('Good', economy, ignore.case = TRUE), 'Good', 'Bad')) %>%
      count(gender, type)
    
    #  gender type n
    #1 Female  Bad 5
    #2 Female Good 3
    #3   Male  Bad 9
    #4   Male Good 3
    

    这会将"Good/Very Good" 转换为一种类型,将"Bad/Very Bad" 转换为另一种类型。

    【讨论】:

      猜你喜欢
      • 2022-01-14
      • 2019-04-09
      • 2017-10-21
      • 1970-01-01
      • 2022-01-14
      • 2019-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多