r - 数据组按 Cut 统计汇总
问题描述
我从多篇研究论文中获得了数百个提供不同年龄小动物体重的数据。我想按年龄对 7 天的体重进行分组和分析。我已成功使用 R 中的 cut 按年龄对数据进行分组,并在每个 7d bin 中具有默认的值数(计数)。但即使经过大量谷歌搜索,我也无法找到一种方法来扩展“切割”以获得每个年龄箱的基本统计摘要,包括平均值、SE、CL 和中位数。这可能吗,有人可以帮助我或为我指明正确的方向吗?
我还查看了 dplyr ,虽然它似乎能够提供统计摘要,但我看不到按 7d 间隔对年龄进行分组的方法。那会是更好的选择吗?
感谢非程序员提供的任何帮助。
附加信息
感谢你们两位的评论。很抱歉提供的信息有限,我希望这能澄清问题。我在 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男MEI男BW
- 21-28 平均 平均 平均
- 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
- 中位数 中位数
- 29-35 平均 平均 平均
- 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
- 中位数 中位数
- 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。
感谢您的评论,很抱歉没有让要求更清楚。我很感激你放弃你的时间来提供帮助。
丹,这是使用 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")
解决方案
如果我理解正确(但请尝试在下一次包含一个可重现的示例),此代码应该:
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)
推荐阅读
- javascript - 检查输入是否相同(多个条件)javascript数组
- sql-server - 具有默认空参数的存储过程中的 CASE 语句
- sql-server - Grabbing Multiple Substrings Between Specific Characters in SQL
- windows - 使用 netsh 工具转发 Rdp 数据包
- model - 如何使用 or (Op.or / $or) 运算符指定该阶段应等于 null 或初级或高级以进行续集?
- heroku - 每个 heroku dyno 应该参加多少用户流量/天?
- arrays - VBA /如何检查字典项目是否存在于另一个字典中?
- generics - 使包装的 F# SRTP 函数通用
- javascript - Javascript/Typescript - 防止表单在提交时重置
- excel - 在 sumifs 公式中将数字作为文本处理