【问题标题】:R aggregate by a variable then find out proportion of a each columnR通过一个变量聚合然后找出每列的比例
【发布时间】:2017-05-20 00:07:10
【问题描述】:

对不起,我已经尽力了,但我没有找到答案。作为初学者,我不确定我能否清楚地提出问题。提前致谢。

所以我有一个数据框,其中包含 24000 行的消费数据。 在这个数据框中,有一系列关于过去两个月内购买的物品数量的变量:
NumberOfCoat、NumberOfShirt、NumberOfPants、NumberOfShoes...
并且有一个通过数字注册的变量“职业”。

所以现在数据看起来像这样

            profession  NumberOfCoat  NumberOfShirt  NumberOfShoes
individu1       1              1             1             1
individu2       3              2             4             1
individu3       2              2             0             0
individu4       6              0             3             2
individu5       5              0             2             3
individu6       7              1             0             5
individu7       4              3             1             2

我想了解各职业的消费结构,得到这样的结果:

           ProportionOfCoat  ProportionOfShirt  ProportionOfShoe...
profession1       0.3                0.5                0.1
profession2       0.1                0.2                0.4
profession3       0.2                0.6                0.1
profession4       0.1                0.1                0.2

不知道是不是很清楚,但最后我想说:

医生购买的服装产品中有 10% 是 T 恤,而教师购买的服装中有 20% 是 T 恤。

最后,我想绘制一个堆叠条形图,其中每个堆叠都缩放为总和为 100%。 我想我们可以 dplyr 吗?

非常感谢!!

【问题讨论】:

  • library(dplyr); df %>% group_by(profession) %>% summarise_all(sum) %>% mutate_at(vars(-profession), prop.table)
  • 欢迎来到 Stack Overflow。这是不止一个问题。请一次只问一个。还请展示您试图获得答案的内容。
  • ...你甚至不需要聚合来制作条形图;只需使用position = 'fill':library(tidyverse); df %>% gather(df, var, val, -profession) %>% ggplot(aes(profession, val, fill = var)) + geom_col(position = 'fill')

标签: r bar-chart plyr


【解决方案1】:
temp <- aggregate( . ~ profession, data=zzz, FUN=sum)
cbind(temp[1],temp[-1]/rowSums(temp[-1]))

或者也使用 prop.table

【讨论】:

    【解决方案2】:

    正如其他人所说,发布一个可重现的示例总是更好,我将尝试发布一个带有我的解决方案的示例,该示例比已经发布的示例更长,但出于同样的原因,可能更清晰。

    首先你应该创建一个示例数据框:

    set.seed(10) # I set a seed cause I´ll use the sample() function
    n <- 1:100 # vector from 1 to 100 to obtain the number of products bought
    p <- 1:8 # vector for obtaining id of professions
    profession <- sample(p,50, replace = TRUE)
    NumberOfCoat <- sample(n,50, replace = TRUE)
    NumberOfShirt <- sample(n,50, replace = TRUE)
    NumberOfShoes <- sample(n,50, replace = TRUE)
    
    df <- as.data.frame(cbind(profession, NumberOfCoat, 
                          NumberOfShirt, NumberOfShoes))
    

    获得数据框后,您可以解释到目前为止您尝试过的内容或可能的解决方案。这里我使用了dplyr

    df <- df %>% group_by(profession) %>% summarize(coats = sum(NumberOfCoat),
                                                shirts = sum(NumberOfShirt),
                                                shoes = sum(NumberOfShoes)) %>%
                 mutate(tot_prod = coats + shirts + shoes,
                        ProportionOfCoat = coats/tot_prod,
                        ProportionOfShirt = shirts/tot_prod,
                        ProportionofShoes = shoes/tot_prod) %>%
                select(profession, ProportionOfCoat, ProportionOfShirt, 
                       ProportionofShoes)
    

    df对应于您显示的第二个数据框,其中您有每个专业购买的每种产品的比例。在我的示例中如下所示:

     profession ProportionOfCoat ProportionOfShirt ProportionofShoes
           <int>            <dbl>             <dbl>             <dbl>
    1          1        0.3910483         0.2343934         0.3745583
    2          2        0.4069641         0.3525571         0.2404788
    3          3        0.3330804         0.3968134         0.2701062
    4          4        0.2740657         0.3952435         0.3306908
    5          5        0.2573991         0.3784753         0.3641256
    6          6        0.2293814         0.3543814         0.4162371
    7          7        0.2245841         0.3955638         0.3798521
    8          8        0.2861635         0.3490566         0.3647799
    

    如果要生成堆叠条形图,则必须将数据重新整形为长格式才能使用ggplot2。正如@alistaire 所说,您可以使用tidyr 包中的gather 函数来实现。

    df <- df %>% gather(product, proportion, -profession) 
    

    最后你可以用ggplot2 绘制它。

    ggplot(df, aes(x=profession, y=proportion, fill=product)) + 
           geom_bar(stat="identity") 
    

    【讨论】:

    • 非常感谢您耐心的回复。它在全球范围内为我工作。但是,我认为这是因为我的数据中的 NA,按专业划分的不同产品的比例总和不是 100% ......最后这些条的长度不均匀......你能告诉我要做什么吗?做 ?再次感谢!
    • 哦!我想可能是因为不同职业的人口数量不均等....比如我的职业1有20人,职业2有300人,职业3有84人...... :'(
    • 这应该没问题,我提供的数据具有相同的特征,df %&gt;% group_by(profession) %&gt;% summarize(np = n())with,你可以检查每个职业有不同的人数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    相关资源
    最近更新 更多