如何使用ggplot2在R中绘制周围刺激时间直方图(PSTH)

如何使用ggplot2在R中绘制周围刺激时间直方图(PSTH),r,ggplot2,neuroscience,R,Ggplot2,Neuroscience,假设我有两个条件,‘a’和‘b’。在“A”条件下,神经元平均每秒发射40个脉冲(Hz),在“b”条件下,平均每秒发射80个脉冲。条件“a”的响应呈现20次,条件“b”呈现10次,每次呈现时间为1000 ms AB <- rbind( ldply( 1:20, function(trial) { data.frame( trial=trial, cond=factor('a',c('a

假设我有两个条件,‘a’和‘b’。在“A”条件下,神经元平均每秒发射40个脉冲(Hz),在“b”条件下,平均每秒发射80个脉冲。条件“a”的响应呈现20次,条件“b”呈现10次,每次呈现时间为1000 ms

AB <- rbind(
    ldply( 1:20, 
        function(trial) { 
          data.frame( 
              trial=trial, 
              cond=factor('a',c('a','b')), 
              spiketime = runif(40,0,1000))
        }
    ), ldply(21:30, 
        function(trial) {
          data.frame(
              trial=trial, 
              cond=factor('b',c('a','b')), 
              spiketime = runif(80,0,1000))
        }
  )
)
但是,这并不是整个演示的平均值,因此,y轴上的值大致相同。我想沿着y轴绘制尖峰率(尖峰/秒),这将表明条件“b”每秒引发大约两倍的尖峰。峰值速率不会随着演示文稿数量的增加而增加,只是变得噪音更小。有没有一种方法可以在不预处理数据帧AB的情况下做到这一点

换言之,我可以按照以下思路做些事情:

qplot(spiketime, data=AB, geom='line',stat='bin',
      y=..count../num_presentations*1000/binwidth, ylab='Spikes per second',
      xlim=c(0,1000), colour=cond, binwidth=100,xlab='Milliseconds')

其中,对于条件“a”,num_表示为20,对于条件“b”,num_表示为10,而1000/b宽度仅为一个常数,以获得正确的单位?

它不会在所有条件下平均;它超过了他们。由于条件a有20x40=800点,而条件b有10*80=800点,因此这些“直方图”下的“面积”将是相同的。您希望某个条件下的每个试验具有相同的权重,而不是每个点具有相同的权重。这必须作为预处理步骤来完成

trial.group <- unique(AB[,c("trial","cond")])
hists <- dlply(AB, .(trial), function(x) {hist(x$spiketime, breaks=10, plot=FALSE)})
hists.avg <- ddply(trial.group, .(cond), function(x) {
  hist.group <- ldply(hists[x$trial], function(y) {
    data.frame(mids=y$mids, counts=y$counts)
  })
  ddply(hist.group, .(mids), summarise, counts=mean(counts))
})

ggplot(data=hists.avg, aes(x=mids, y=counts, colour=cond)) + geom_line()
以下是一个解决方案:

AB$ntrial <- ifelse(AB$cond=="a", 20, 10)
ggplot(AB, aes(spiketime, ntrial=ntrial, colour=cond)) + 
  stat_bin(aes(y=..count../ntrial*1000/100), binwidth=100, geom="line", position="identity") +
  xlim(0,1000) + 
  labs(x='Milliseconds', y="Firing rate [times/s]")

AB$ntrial对不起,有个问题!我希望它在演示文稿上平均,而不是在条件下平均。附加的条件表示不会改变发射率(我想在柱状图中绘制),它只会减少测量的噪音。按照您构建数据的方式,在条件a中每秒发射40次,在条件b中每秒发射80次。你只是在改变第二次开火的位置。您是否希望在1/10秒(100毫秒)内获得发射率(发射次数),并查看这些发射的平均值?如果是这样,我的解决方案就是这样。20次发射/秒的图表噪音比40次低(但速率也较低;如预期的那样,大约每100毫秒发射4次)。此外,我应该说在条件内对演示进行平均,而不是在条件下。我试图通过预处理来避免解决此问题,但它看起来确实解决了问题。我喜欢你的“编辑1”。我自己也在做这件事,并想出了一个不那么优雅的解决方案。非常感谢!不幸的是,Hadley(该软件包的作者)表示,使用额外的美学(ntrial)是一种未定义的行为。在某些情况下,它可能会导致“eval(expr、envir、enclose)中出错:找不到对象“ntrial”。
tmp <- as.data.frame(table(unique(AB[,c("trial","cond")])["cond"]))
names(tmp) <- c("cond","ntrial")
AB <- merge(AB, tmp)

ggplot(AB, aes(spiketime, ntrial=ntrial, colour=cond)) + 
  stat_bin(aes(y=..count../ntrial*1000/100), binwidth=100, geom="line", position="identity") +
  xlim(0,1000) + 
  labs(x='Milliseconds', y="Firing rate [times/s]")
AB$ntrial <- ifelse(AB$cond=="a", 20, 10)
ggplot(AB, aes(spiketime, ntrial=ntrial, colour=cond)) + 
  stat_bin(aes(y=..count../ntrial*1000/100), binwidth=100, geom="line", position="identity") +
  xlim(0,1000) + 
  labs(x='Milliseconds', y="Firing rate [times/s]")