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

发布于 2024-11-29 20:41:53 字数 1223 浏览 0 评论 0原文

假设我有两个条件,“a”和“b”。神经元在条件“a”下平均每秒激发 40 个尖峰,在条件“b”下平均每秒激发 80 个尖峰。对条件“a”的响应出现 20 次,对条件“b”的响应出现 10 次,每次出现 1000 毫秒。

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))
        }
  )
)

可以使用以下方法绘制简单的直方图:

qplot(spiketime, data=AB, geom='line',stat='bin',y=..count.., 
      xlim=c(0,1000), colour=cond, binwidth=100,xlab='Milliseconds')

但是,这不会对演示文稿进行平均,因此 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_presentations 为 20,条件“b”的 num_presentations 为 10,并且 1000/binwidth 只是一个常量以使单位正确?

Say that I have two conditions, 'a' and 'b'. A neuron fires on average 40 spikes / second (Hz) in condition 'a' and 80 spikes / second in condition 'b'. The response to condition 'a' is presented 20 times and condition 'b' is presented 10 times, with each presentation for 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))
        }
  )
)

A simple histogram can be plotted with:

qplot(spiketime, data=AB, geom='line',stat='bin',y=..count.., 
      xlim=c(0,1000), colour=cond, binwidth=100,xlab='Milliseconds')

However, this does not average over the presentations, and hence, the values on the y axis are about the same. I would like to plot the spiking rate (spikes/second) along the y-axis, which would show that condition 'b' elicits about twice as many spikes per second. The spiking rate does not increase as number of presentations increase, it just becomes less noisy. Is there a way to do this without pre-processing the dataframe AB?

In other words, can I do something along the lines of:

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')

where num_presentations would be 20 for condition 'a' and 10 for condition 'b' and 1000/binwidth would just be a constant to get the unit correct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

策马西风 2024-12-06 20:41:53

这是一个解决方案:

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]")

Here is a solution:

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]")

月竹挽风 2024-12-06 20:41:53

它不会对条件进行平均;它总结了它们。由于条件 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()

这是使用 hist 分别对每个试验的数据进行分类,然后对试验组的计数进行平均。这使得每个条件具有相同的权重,并且每个条件内的每个试验具有相同的权重。

在这里,我采用 Kohske 的解决方案,但计算试验次数而不是显式输入:

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]")

It does not average over the conditions; it sums over them. Since condition a has 20x40 = 800 points and condition b has 10*80 = 800 points, the "area" under these "histograms" will be the same. You want each trial within a condition to have equal weight, not each point to have equal weight. That will have to be done as a pre-processing step.

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()

This is using hist to bin the data for each trial separately, then averaging the counts over the trial groups. This gives each condition equal weight, and each trial equal weight within each condition.

Here I take kohske's solution, but calculate the number of trials instead of entering them explicitly:

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]")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文