【问题标题】:Grouping the dataframe based on one variable基于一个变量对数据框进行分组
【发布时间】:2015-02-20 09:22:14
【问题描述】:

我有一个包含 10 个变量的数据框,所有变量都是数字,变量名称之一是年龄,我想根据 age.example 对观察结果进行分组。 17至18岁一组,19-22岁另一组,然后每排应附在每组上。结果应该是用于进一步操作的数据框。 数据框模型:

A   B   AGE
25  50  17
30  42  22
50  60  19
65  105 17
355 400 21
68  47  20
115 98  18
25  75  19

我想要这样的结果

17-18 
A   B   AGE
25  50  17
65  105 17
115 98  18

19-22
A   B   AGE
30  42  22
50  60  19
355 400 21
68  47  20
115 98  18
25  75  19

我确实使用 split 函数根据 Age var 对数据集进行了分组,现在我关心的是如何操作分组数据。例如:答案看起来像

$1

  A   B   AGE
  25  50  17
  65  105 17
  115 98  18

$2
A   B   AGE
    30  42  22
    50  60  19
    355 400 21
    68  47  20
    115 98  18
    25  75  19

我的问题是如何访问每个组以进行进一步操作? 例如:如果我想分别对每个组进行 t 检验?

【问题讨论】:

  • 您可以尝试cut 进行年龄分组
  • 我试过了,Rstudio 说它无法识别!
  • 试试split(df1, cut(df1$AGE, breaks=c(16, 18, 22), labels=FALSE))

标签: r variables grouping


【解决方案1】:

拆分功能适用于数据帧。使用cut 和'breaks' 或findInterval 和一组适当的切点(如果您使用命名参数,则命名为'vec')作为分组标准,split 的第二个参数。 cut 的默认值是右侧封闭的间隔,findInterval 的默认值是左侧封闭的区间。

> split(dat, findInterval(dat$AGE, c(17, 19.5, 22.5)))
$`1`
    A   B AGE
1  25  50  17
3  50  60  19
4  65 105  17
7 115  98  18
8  25  75  19

$`2`
    A   B AGE
2  30  42  22
5 355 400  21
6  68  47  20

【讨论】:

    【解决方案2】:

    这是cut的方法

    lst <- split(df1, cut(df1$AGE, breaks=c(16, 18, 22), labels=FALSE))
    lst
    # $`1`
    #   A   B AGE
    #1  25  50  17
    #4  65 105  17
    #7 115  98  18
    
    #$`2`
    #   A   B AGE
    #2  30  42  22
    #3  50  60  19
    #5 355 400  21
    #6  68  47  20
    #8  25  75  19
    

    更新

    如果您需要为每个“列表”元素查找列的summean

    lapply(lst, function(x) rbind(colSums(x[-3]),colMeans(x[-3])))
    

    但是,如果目标是根据组找到汇总统计信息,则可以使用任何聚合函数来完成

     library(dplyr)
     df1 %>% 
         group_by(grp=cut(AGE, breaks=c(16, 18, 22), labels=FALSE)) %>% 
         summarise_each(funs(sum=sum(., na.rm=TRUE),
                          mean=mean(., na.rm=TRUE)), A:B)
     #   grp A_sum B_sum    A_mean    B_mean
     #1   1   205   253  68.33333  84.33333
     #2   2   528   624 105.60000 124.80000
    

    或者使用来自base Raggregate

     do.call(data.frame,
       aggregate(cbind(A,B)~cbind(grp=cut(AGE, breaks=c(16, 18, 22), 
        labels=FALSE)), df1, function(x) c(sum=sum(x), mean=mean(x))))
    

    数据

    df1 <- structure(list(A = c(25L, 30L, 50L, 65L, 355L, 68L, 115L, 25L
    ), B = c(50L, 42L, 60L, 105L, 400L, 47L, 98L, 75L), AGE = c(17L, 
    22L, 19L, 17L, 21L, 20L, 18L, 19L)), .Names = c("A", "B", "AGE"
    ), class = "data.frame", row.names = c(NA, -8L))
    

    【讨论】:

    • 在这个答案的情况下 split(df1, cut(df1$AGE, breaks=c(16, 18, 22), labels=FALSE)) 年龄停止在 22. 对我来说右侧应该开放......所以第一个答案是首选。 findInterval 之一....感谢您的时间和精力。
    • 很抱歉再次打扰您,我很难使用数据!我的意思是如何使用拆分数据?我想在创建的子集上找到总和、平均值等!
    • @MerryKumar 请具体说明。是否要在两个子集上查找列或行的sumaverage
    • 除年龄之外的所有其他变量的总和和平均值,因为我们根据每个组的年龄进行分组!
    • @MerryKumar 请立即检查
    猜你喜欢
    • 1970-01-01
    • 2011-11-27
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多