如何高效统计各受试者DataFrame中4×4网格单元格的数据频次
问题描述
我有一个包含Subject、RT1、RT2列的DataFrame,生成代码如下:
df <- data.frame(Subject = c(rep(1,15), rep(2,15)), RT1=rep(seq(100,1500,100),2), RT2 = rep(seq(200,3000,200),2))
需要按每个受试者,统计数据点落在指定4×4网格各单元格中的数量/频次(示例数据中两受试者数据相同,但实际数据不同)。网格的轴值定义如下:
x_axis <- c(220,350,700,1250,1800) y_axis <- c(100,700,1400,2500,3500)
期望输出类似如下格式(示例为单个受试者):
df2 <- data.frame("<x1"= c(1,0,0,0,0), "x1-x2"= c(0,2,0,0,0), "x2-x3"= c(0,0,4,0,0), "x4-x5"= c(0,0,0,3,0) )
已知一种逐个单元格统计的方法,但效率极低,需为每个单元格重复编写代码:
df %>% group_by(Subject)%>% count(between(df$RT1,0,180),between(df$RT2 ,0,210))%>% set_names(c("RT1","RT2","n"))%>% filter(if_all(RT1:RT2, ~ . %in% TRUE))
需要高效的解决方案。
高效解决方案
可以利用cut()函数批量对RT1和RT2做区间分箱,结合分组统计与数据重塑实现,无需逐个单元格编写重复代码:
步骤1:定义区间标签
先为x、y轴的区间生成匹配需求的标签:
# 生成x轴区间标签 x_labels <- c("<x1", paste0("x", 1:(length(x_axis)-2), "-x", 2:(length(x_axis)-1)), paste0("x", length(x_axis)-1, "-x", length(x_axis))) # 生成y轴区间标签(对应输出的行) y_labels <- c("<y1", paste0("y", 1:(length(y_axis)-2), "-y", 2:(length(y_axis)-1)), paste0("y", length(y_axis)-1, "-y", length(y_axis)))
步骤2:分箱+统计+重塑
通过cut()完成批量分箱,再按受试者、区间统计频次,最后转为目标宽表格式:
library(tidyverse) result <- df %>% group_by(Subject) %>% mutate( # 对RT1按x_axis分箱,补充左边界0,左闭右开 RT1_bin = cut(RT1, breaks = c(0, x_axis), labels = x_labels, include.lowest = TRUE), # 对RT2按y_axis分箱,补充左边界0 RT2_bin = cut(RT2, breaks = c(0, y_axis), labels = y_labels, include.lowest = TRUE) ) %>% count(RT1_bin, RT2_bin, name = "freq") %>% # 转为宽表,缺失单元格填充0 pivot_wider(names_from = RT1_bin, values_from = freq, values_fill = 0) %>% # 将y区间设为行名(可选,匹配示例格式) column_to_rownames("RT2_bin")
关键说明
cut()一次性完成所有区间划分,替代重复的between()逻辑pivot_wider()自动将x区间转为列、y区间转为行,缺失单元格自动补0- 结果按受试者分组,每个受试者对应一个符合需求的频次矩阵
示例输出
以测试数据为例,受试者1的输出如下:
<x1 x1-x2 x2-x3 x3-x4 x4-x5 <y1 1 0 0 0 0 y1-y2 0 2 0 0 0 y2-y3 0 0 4 0 0 y3-y4 0 0 0 3 0 y4-y5 0 0 0 0 5
内容的提问来源于stack exchange,提问作者L_ROTOLO
相关产品推荐
相关产品推荐

