最近,我一直在使用包含各种类型的多维数据的数据结构 . 就我而言,数组中的主题录音包含以下维度:
主题ID(dim = 9)
型号(昏暗= 8)
试验(昏暗= 30)
每次试用样品(昏暗= 30)
在实验期间,受试者从前15个试验的分布A接收数据,然后在最后15个试验中接收分布B,反之亦然 . 这在我的数据中表示为“AB”组或“BA”组 . 受试者1,3,4,5,7,8,9在AB组中,受试者2,6在BA组中 .
我经常想要遍历所有这些信息以查找摘要统计信息,将其作为数据帧格式化为长格式,然后将其提供给ggplot . 通常,我最终会在进程中使用一些嵌套结构,然后我必须使用嵌套的 lapply 进行循环 . 以下是我过去设置此类数据的方法 . 在此可再现示例中,将随机数组的样本主题记录分配给 recordings 变量 .
在此代码中,我计算每个主题(1:9)在每个分布上的平均值和标准差("A"或"B",每个15个试验) . rbind 用于将数据融合成长格式(不知道如何在我的情况下用 reshape2::melt 实现相同的效果) . 然后使用额外的列手动注释数据以供ggplot使用 . 其中一列("group")指定来自哪些主题的主题("AB"或"BA") .
subj
nTrials
distr
model
size
recordings
dat1
lapply(distr, function(x) lapply(subj, function(y) recordings[y, model, x, ] %>% t()) %>%
lapply(., function(z) {
as.data.frame(z) %>%
mutate(mean = rowMeans(.),
sd = apply(., 1, sd)) %>%
select(mean, sd)
}) %>%
do.call(rbind, .)) %>%
do.call(rbind, .) %>%
mutate(distribution = c(rep("A", size/2), rep("B", size/2)),
time = rep(seq(0, 2.9, 0.1), length(subj)*2),
subject = rep(subj, each = nTrials) %>% rep(., 2),
group = rep(c("AB", "BA", "AB", "AB", "AB", "BA", "AB", "AB", "AB"), each = nTrials) %>% rep(., 2)) %>%
set_colnames(c("mean", "se", "distribution", "time", "subject", "group"))
ggplot(dat1, aes(time, mean, ymin = mean-se, ymax = mean+se, color = distribution)) +
geom_line() +
geom_errorbar() +
geom_hline(yintercept = 0, linetype = "dashed") +
facet_wrap(group ~ subject) +
xlab("Time (sec)") +
ylab("Recording") +
scale_color_manual(values = c("red3", "blue3")) +
theme_bw()
好吧,但是如果我想将数据压缩到具有两个方面的图表中,AB在一个方面的所有主题的平均值和标准差以及另一个方面的BA中所有主题的平均值和标准差怎么办?
这是我之前所知,我仍然不得不将它包装在 distr 列表的另一个lapply中,以及AB或BA中的主题的另一个包装!嵌套开始变得荒谬,我的代码已经很难阅读了 .
subjBA
subjAB
subj.l
# To do:
# Replace distr[[1]] with an lapply loop over both list elements of distr
# Replace subj.l[[1]] with an lapply loop over both list elements of subj.l
lapply(subj.l[[1]], function(y) recordings[y, M, distr[[1]],] %>% t()) %>%
lapply(., function(z) {
as.data.frame(z) %>%
mutate(mean = rowMeans(.),
sd = apply(., 1, sd)) %>%
select(mean, sd) %>%
do.call(rbind, .)
}) %>%
do.call(rbind,. ) %>%
split(., rownames(.)) %>%
lapply(., function(b) matrix(b, nrow = 4) %>%
colMeans())
当然有更好的方法来做到这一点!在基础R( aggregate ?),dplyr或其他可能使这种过程更简单的包中有汇总函数吗?我之前没有使用过 data.table 但如果这是最干净的解决方案,我可能会咬紧牙关并强迫自己学习 .