使用列名中的时间值重塑 R 中的数据

Reshaping data in R with time values in column names

我有一个数据框,看起来像这样(简化):

     data1.time1 data1.time2 data2.time1 data2.time2 data3.time1 group
 1          1.53        2.01        6.49        5.22        3.46    A
 ...
 24         2.12        3.14        4.96        4.89        3.81    C

在 1..27 中实际上有 dataK.timeT K,在 1..8 的一些(但可能不是全部)中有 T。

我想将数据重新排列到 K 个数据框中,以便我可以为每个 K 绘制三组 A、B 中每一组的汇总数据(现在假设均值和均值±标准差) , 和 C. 也就是说,我想要 27 个图表,每个图表三行,并标记偏差。

重新排列数据后,按组折叠、计算汇总统计等应该很容易。但我不太确定如何将数据放入此表单中。我查看了 reshape 包,它建议将其融合为键值存储格式并从那里重新排列,但它似乎不支持包含 T 值的列,就像我在这里看到的那样。

有什么好的方法吗?我很愿意用R以外的东西来做这个,因为我可以在转换后将结果导入R。

可以用 dplyr 做这样的事情:

for(i in 1:K){ ## for 1:27
  my.data.ind <- paste0("data",i,"|group") ## "datai|group"
  one.month <- select(data, contains(my.data.ind) %>% ## grab cols that have these
                  group_by(group) %>% ## group by your group
                  summarise_each(funs(mean), funs(sd)) ## find mean for each col within each group
}

这应该会给您留下一个 3xT 数据框,其中每个组随时间 T

的平均值

在创建与您的结构相似的假数据后,我们将宽格式转换为长格式,制作一个 "tidy" 数据框,准备好使用 ggplot2 进行绘图。

library(reshape2)
library(ggplot2)
library(dplyr)

创建虚假数据

set.seed(194)
dat = data.frame(replicate(27*8, cumsum(rnorm(24*3))))

names(dat) = paste0(rep(paste0("data",1:27), each=8), ".", rep(paste0("time",1:8), 27))

dat$group = rep(LETTERS[1:3], each=24)

删除一些列,以便不同数据源的时间点数量不同:

dat = dat[ , -c(2,4,9,43,56,78,100:103,115:116,134:136,202,205)]

从宽格式重塑为长格式

datl = melt(dat, id.var="group")

将数据源和时间点拆分到单独的列中:

datl$source = gsub("(.*)\..*","\1", datl$variable)
datl$time = as.numeric(gsub(".*time(.*)","\1", datl$variable))

# Order data frame names by number (rather than alphabetically)
datl$source = factor(datl$source, levels=paste0("data",1:length(unique(datl$source))))

使用 ggplot2 绘制数据

# Helper function for plotting standard deviation
sdFnc = function(x) {
  vals = c(mean(x) - sd(x), mean(x) + sd(x))
  names(vals) = c("ymin", "ymax")
  vals
}

pd = position_dodge(0.7)

ggplot(datl, aes(time, value, group=group, color=group)) + 
  stat_summary(fun.y=mean, geom="line", position=pd) +
  stat_summary(fun.data=sdFnc, geom="errorbar", width=0.4, position=pd) +
  stat_summary(fun.y=mean, geom="point", position=pd) +
  facet_wrap(~source, ncol=3) +
  theme_bw()

原始(不必要地复杂)重塑代码。 (注意,此代码将不再适用于更新的(假的)数据集,因为时间列的数量不再统一):

# Convert data source from wide to long
datl = data.frame()
for (i in seq(1,27*8,8)) {

  tmp.dat = dat[, c(i:(i+7),grep("group",names(dat)))]
  tmp.dat$source = gsub("(.*)\..*", "\1", names(tmp.dat)[1])
  names(tmp.dat)[1:8] = 1:8

  #datl = rbind(datl, tmp.dat)
  datl = bind_rows(datl, tmp.dat)  # Updated based on comment
}

datl$source = factor(datl$source, levels=paste0("data",1:27))

# Convert time from wide to long
datl = melt(datl, id.var = c("source","group"), variable.name="time")