首页 > 解决方案 > 数据组按 Cut 统计汇总

问题描述

我从多篇研究论文中获得了数百个提供不同年龄小动物体重的数据。我想按年龄对 7 天的体重进行分组和分析。我已成功使用 R 中的 cut 按年龄对数据进行分组,并在每个 7d bin 中具有默认的值数(计数)。但即使经过大量谷歌搜索,我也无法找到一种方法来扩展“切割”以获得每个年龄箱的基本统计摘要,包括平均值、SE、CL 和中位数。这可能吗,有人可以帮助我或为我指明正确的方向吗?

我还查看了 dplyr ,虽然它似乎能够提供统计摘要,但我看不到按 7d 间隔对年龄进行分组的方法。那会是更好的选择吗?

感谢非程序员提供的任何帮助。

附加信息

感谢你们两位的评论。很抱歉提供的信息有限,我希望这能澄清问题。我在 Excel 中有超过 2000 行数据。行是以天为单位的年龄,列是'MaleFI'、MaleMEI'和 MaleBW,其中 FI 是食物摄入量,MEI 是可代谢能量摄入量,BW 是体重。部分数据如下所示。通常我可以使用 Excel 数据透视表来分析数据,但这不包括计算中位数或标准误差的选项;Power Pivot 可以但不分组!所以数据如下(按天数排序,无空格):

年龄是连续的,可能会上升到大约 900,每个年龄都有不同数量的值。

目标是按 7d 周期分组,正如我提到的,对每个组进行统计分析:

这是我用来对数据进行分组的代码,但正如我所提到的,事后看来,可能使用 dplyr 和 group_by 和 summarise 可能是更好的方法。

library("xlsx")
library("dplyr")
Pivot.data <- read.xlsx(file.choose(), 1)  # read first sheet
pt<-cut(Pivot.data$Age, breaks=seq(21, 800, by=7))
table(pt)

输出为 (21,28] (28,35] (35,42] (42,49] (49,56] (56,63] (63,70] (70,77)
6 15 41 73 92 98 95 ) 99

我会对范围的格式感到满意,即 (21,28] 等而不是 21-28。

感谢您的评论,很抱歉没有让要求更清楚。我很感激你放弃你的时间来提供帮助。

丹,这是使用 dput 的输出:

dput(head(Pivot.data, 20)) 结构(list(Age = c(28, 28, 28, 28, 28, 28, 30, 35, 35, 35, 35, 35, 35, 35, 35, 35 , 35, 35, 35, 35), MaleFI = c(14.62, 13.82, 10.6691449814126, 15.9859154929577, 11.7, 14.0273778252258, 13.5877862595419, 17.73, 17.93, 17.99, 22.1214285714286, 17.6, 22.48, 21.7, 19.6, 21.4, 21.25, 20.37, 19.3215613382899, 23.169014084507), MaleMEI = c(212.66252, 201.02572, 144.342862453531, 216.273450704225, 160.171462269, 204.047711328562, 197.653240885495, 257.90058, 241.76812, 261.68254, 298.285342857143, 238.3216, 304.40168, 315.6482, 285.1016, 311.2844, 309.1025, 296.30202, 261.401403345724, 313.453591549295), MaleBW = c(121.68, 112.15, 85.7142857142856, 143.181818181818, 109.20245398773, 89.8187948576385, 126.522593320235, 131.96, 127.98, 142.57, 126.92, 146.9, 145.45, 131.9, 129.8, 132.4, 191.21, 179.44, 138.095238095238, 202.272727272727)), row.names = c(NA, 20L), class = "data.frame")

标签: rdplyrgroupingcut

解决方案


如果我理解正确(但请尝试在下一次包含一个可重现的示例),此代码应该:

library(tidyverse)
your_df %>% 
  # mutate(Age_cl = cut(Age, c(-Inf,30,60,Inf))) %>% 
  mutate(Age_cl = cut(Age, breaks=c(-Inf, seq(min(Age), max(Age), by=7), Inf), right = F)) %>%
  group_by(Age_cl) %>% 
  summarise(
    n=n(),
    m=mean(Age, na.rm=T),
    sd=sd(Age, na.rm=T),
    max=max(Age, na.rm=T),
    min=min(Age, na.rm=T)
  )

您创建作为age_cl的结果的新列cut,然后按此新列和summarise(或者您可以mutate根据需要再次)分组您想要的所有摘要。

您还可以使用summarise_at函数列表:

your_df %>% 
  mutate(Age_cl = cut(Age, c(-Inf,30,60,Inf))) %>% 
  group_by(Age_cl) %>% 
  summarise_at("Age", list(m=mean, sd=sd, max=max, min=min), na.rm=T)

请注意,其他参数将适用于所有函数,就像na.rm这里一样。

编辑:对于记录,似乎有一种方法可以使用该summary函数,但您必须将其结果转换为 data.frame 才能工作。summary与编写上述函数相比,这可能不值得。这是数据集的示例iris

iris %>% 
  mutate(Sepal.Length_cl = cut(Sepal.Length, c(-Inf,5,6,Inf))) %>% 
  group_by(Sepal.Length_cl) %>% 
  group_modify(~summary(.$Sepal.Length) %>% unclass %>% t %>% as.data.frame)

推荐阅读