【问题标题】:Stastistical summary of data group by Cut数据组按 Cut 统计汇总
【发布时间】:2020-05-05 18:32:12
【问题描述】:

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

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

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

附加信息

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

  • 年龄男FI MaleMEI男BW
  • 28.00 14.62 212.66 121.68
  • 28.00 13.82 201.03 112.15
  • 28.00 13.82 201.03 112.15
  • 29.00 15.12 220.31 125.14 ...

年龄是连续的,可能高达 900 左右,每个年龄的值数量不同。

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

  • 年龄男FI MaleMEI MaleBW
  • 21-28 均值 均值 均值
  • SE SE SE
  • 中位数 中位数
  • 29-35 均值 均值 均值
  • SE SE SE
  • 中位数 中位数
  • 36-42 等

这是我用来对数据进行分组的代码,但正如我所提到的,事后看来,使用 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。

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

Dan,这是使用 dput 的输出:

dput(head(Pivot.data, 20)) 结构(列表(年龄 = 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")

【问题讨论】:

  • 嗨,欢迎来到 SO。为了让我们帮助您,您需要与我们分享一个可重现的示例:我们可以运行的代码,它可以重现您的数据集和预期的输出。在 R 中,您可以使用 dput(head(your_df, 20)) 并将结果发布到您的问题中。
  • 我希望上面的编辑更清楚地显示需求。
  • 感谢您的努力,但现在还不是。您没有按照我的建议使用dput,因此您的代码只能由您使用,这不是很有帮助。

标签: r dplyr grouping cut


【解决方案1】:

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

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)

【讨论】:

  • 谢谢。我会试试你的建议。
  • 我完全按照您的建议使用了原始代码,但使用了我的实际 df 名称。我收到以下错误:错误:列 age_cl 的长度必须为 1996(行数)或 1,而不是 13。1996 与导入的 Excel 工作表中的数据行数匹配。
  • @GrahamTobin 我将age 更正为Age,它对您的dput 输出有效。再试一次:-)
  • 几乎精彩!我在上面进行了更改,但问题仍然存在。我收到一条错误消息,提示 Tidyverse 使用的是旧版本的 rlang。 '更新' rlang 产生了相同的错误消息。我手动删除了所有库(我应该只尝试 rlang)。安装了最新版本的 rlang 包,然后是 tidyverse 包。代码运行良好。我扩展了总结部分以包括 MaleFI、MaleMEI、MaleBW 和中位数。完美和数值匹配 Excel 数据透视表。我已经手动添加了我需要的部分年龄范围,这也有效。还有一期。
  • 丹,我应该将当前解决方案粘贴为对原始问题的编辑吗?在其他地方没见过类似的东西。现在是金星!我可以手动粘贴年龄范围来计算 iec(21、28、35、42 等),但使用为范围 (21、900) 和间隔设置最小值和最大值的代码会更优雅(7)。类似'breaks=seq(21, 800, by=7)'。
猜你喜欢
  • 1970-01-01
  • 2020-12-03
  • 1970-01-01
  • 2020-10-13
  • 2019-06-20
  • 1970-01-01
  • 2012-04-08
  • 1970-01-01
相关资源
最近更新 更多