【问题标题】:Reducing data in data frame to plot data in R减少数据框中的数据以在 R 中绘制数据
【发布时间】:2013-12-29 22:50:58
【问题描述】:

我对编程很陌生,所以我提前为我缺乏 R 专业知识而道歉。我是一名对瞳孔测量感兴趣的博士生,我刚刚记录了参与者在两种条件下(简单和困难)执行听力任务的学生反应。每个试验的瞳孔响应兴趣期约为 20 秒,我希望能够在 R 上为每个参与者绘制此数据。眼动仪采样率为 1000Hz,每个参与者完成了 92 次试验。因此,我目前拥有的每个参与者的数据包括近 200 万行。我曾尝试使用 ggplot2 绘制此图,但不出所料,该图非常混乱。

我一直在尝试找到一种减少数据的方法,以便我可以将其绘制在 R 上。理想情况下,我想取每 1000 个样本(即 1 秒的记录)的平均瞳孔大小值在每个参与者的所有 92 次试验中。有了这些信息,我将创建一个新的数据框,用于绘制两种聆听条件(简单和困难)的 1-20 秒的平均斜率。

这是我的数据框的当前结构;

> str(ppt53data)
'data.frame':   1915391 obs. of  6 variables:
 $ RECORDING_SESSION_LABEL: Factor w/ 1 level "ppt53": 1 1 1 1 1 1 1 1 1 1 ...
 $ listening_condition    : Factor w/ 2 levels "Easy","Hard": 2 2 2 2 2 2 2 2 2 2 ...
 $ RIGHT_PUPIL_SIZE       : Factor w/ 3690 levels ".","0.00","1000.00",..: 3266 3264 3263 3262 3262 3260 3257 3254 3252 3252 ...
 $ TIMESTAMP              : num  262587 262588 262589 262590 262591 ...
 $ TRIAL_START_TIME       : int  262587 262587 262587 262587 262587 262587 262587 262587 262587 262587 ...
 $ TrialTime              : num  0 1 2 3 4 5 6 7 8 9 ...
 - attr(*, "na.action")=Class 'omit'  Named int [1:278344] 873 874 875 876 877 878 879 880 881 882 ...
  .. ..- attr(*, "names")= chr [1:278344] "873" "874" "875" "876" ...

“TrialTime”变量指定每次试验的样本(即毫秒)。谁能告诉我下一步我应该采取哪一步?我认为将我的数据安排到单独的数据框中是有意义的,这将允许我计算我想要的平均值(跨试验和每 1000 个样本)。但是,我不确定最有效/最好的方法是什么。

很抱歉,我不能更具体。任何粗略的指导将不胜感激。

【问题讨论】:

  • 恕我直言,如果您将数据发布到我们可以获取的地方(Dropbox?)会更好。或者至少是一个有代表性的子集。
  • 仅供参考:RIGHT_PUPIL_SIZE 中包含非数字数据 - 您可以通过在导入中将它们设置为 na.strings 来摆脱这种情况。 read.csv("myfile.csv",na.strings=".")
  • Brandon,感谢您指出这一点 - 我刚刚更改了该变量,使其只是数字数据。 JLHoward,感谢您的评论 - 如果我有任何疑问,我会尝试发布我的数据。

标签: r plot


【解决方案1】:

一些粗略的指导:

library(plyr)

ppt53data.summarized <- ddply(ppt53data, .(TrialTime), summarize, mean = mean(RIGHT_PUPIL_SIZE))

这告诉它为每个唯一的 TrialTime 计算右瞳孔的平均大小。也许看看它的工作原理会帮助您弄清楚如何描述您的需求?

假设每个 TrailTime 内有 1000 多个观测值,可以随机选择:

set.seed(42)
ppt53data.summarized <- ddply(ppt53data, .(TrialTime), summarize, mean = mean(sample(RIGHT_PUPIL_SIZE,1000)))

【讨论】:

  • 这段代码被证明非常有用,因为它执行了我打算完成的任务之一(每次试验中每秒的平均瞳孔大小)。我希望能够使用类似的代码来查找每 1000 个样本的平均值。使用 ddply() 函数,有没有办法将平均函数应用于数据中的每 1000 个样本,而不是对每个唯一值都执行此操作(如您提供的代码中所示)?
  • 我将通过一个示例更新答案,该示例向您展示如何随机抽取 1000 个样本。
【解决方案2】:

我认为对于具有多个聚合级别的如此大的数据块,您将需要使用data.table。我可能对您的数据进行了错误的结构化,但希望这会给您一个想法:

require(data.table)
require(ggplot2)

#100 patient * 20,000 observations (1-20,000 ms)
ppt53data<-data.frame(
  RECORDING_SESSION_LABEL=paste0("pat-",rep(1:100,each=20000)),    #patients
  listening_condition=sample(c("Easy","Hard"),2000000,replace=T),  #Easy/Hard
  RIGHT_PUPIL_SIZE=rnorm(2000000,3000,500),                        #Pupil Size
  TrialTime=rep(1:20000,100)                                       #ms from start
)

# group in 1000ms blocks
ppt53data$group<-cut(ppt53data$TrialTime,c(0,seq(1000,20000,1000),Inf))

unique(ppt53data$group)

#convert frame to table
dt.ppt53data<-data.table(ppt53data)

#index
setkey(dt.ppt53data, RECORDING_SESSION_LABEL, group)

#create data.frame of aggregated plot data
plot.data<-data.frame(dt.ppt53data[,list(RIGHT_PUPIL_SIZE=mean(RIGHT_PUPIL_SIZE)),by=list(group)])

#plot with ggplot2
ggplot(plot.data)+geom_bar(aes(group,RIGHT_PUPIL_SIZE,stat="identity",fill=group)) +
  theme(axis.text.x=element_text(angle=-90))+
  coord_cartesian(ylim=c(2995,3005))

【讨论】:

  • 谢谢,我很欣赏这个例子。我遇到的一个问题是试图总结每一秒(每 1000 毫秒)。我认为您在这里演示的方式(可以理解)假设每个患者正好有 20000 行。不幸的是,每个患者的行/样本长度不同。所以,我想做的是添加一个变量,它基于这种标签描述每个样本适用于哪一秒(例如 1:20); 1:1000 = 1、1001:2000 = 2、2001:3000 = 3,依此类推,直到样本结束。你能想出一个办法吗?
  • @Ronan 当然 - 对 cut() 调用的一个快速更改,我将在上面进行 - 'ppt53data$group
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 2020-08-23
  • 1970-01-01
  • 1970-01-01
  • 2021-03-13
  • 2021-02-10
  • 2016-04-04
相关资源
最近更新 更多