平均阴影度为95%的曲线

时间:2018-11-03 19:08:22

标签: r ggplot2

我有以下数据,

Data = data.frame(Participant = rep(sprintf("part%03d", 1:100), each=100),
                  Group = rep(c(0,1), each=5*1e3),
                  Evidence = rnorm(1e4),
                  CorrectOrNot = c(rbinom(5*1e3, size=1, prob=.3),
                                   rbinom(5*1e3, size=1, prob=.6)))

其中“参与者”是每个参与者的索引,“组”每个参与者被分配的条件,“证据”是每个参与者的刺激的“强度”,“ CorrectOrNot”是每个刺激的答案的正确性每个参与者。

因此,我对每个参与者进行了逻辑回归,以证明证据和正确答案的概率之间的关系。


plot(1, type="n", xlab="Evidence", ylab="probCorrect", 
     xlim=c(-3, 3), ylim=c(0, 1))

for (i in 1:100)
{
  part = sprintf("part%03d", i)
  test = Data[Data$Participant==part,]

  fit = glm(CorrectOrNot ~ Evidence, test, family=binomial)
  newDat = data.frame(Evidence=seq(min(test$Evidence),max(test$Evidence),len=100))
  newDat$pc = predict(fit, newdata=newDat, type="response")

  lines(pc ~ Evidence, newDat, col=ifelse(test$Group[1]==0, "green", "red"), lwd=2)
}

legend(-3, 1, legend=c("Group 0", "Group 1"),
       col=c("green", "red"), lty=1:2, cex=0.6)

为使结果曲线可视化,我编写了上面的代码,结果看起来很混乱。因此,我想将这些线平均化为每组中的两条代表性线,并在其周围的阴影表示每组中95%的“范围”。

任何帮助,包括使用ggplot2的帮助,将不胜感激。

1 个答案:

答案 0 :(得分:1)

tidyverse 程序包(还包括ggplot2)可以帮助我们稍微重新组织您的代码。例如,我们可以对Participant列的每个唯一值进行一系列操作,而不是进行显式循环:

library(tidyverse)

newDat2 <- Data %>% 
  nest(-Participant) %>% 
  mutate(
    smoothDat = map(data, function(x) data.frame(Group = x$Group[1], Evidence=seq(min(x$Evidence),max(x$Evidence),len=100))),
    fit = map(data, function(x) glm(CorrectOrNot ~ Evidence, x, family=binomial)),
    predict = map2(smoothDat, fit, function(s, f) {
      s$pc <- predict(f, newdata = s, type = 'response')
      return(s)
    })
  )

在对mutate的调用中,“ smoothDat”创建用于生成预测的数据,“ fit”为每个参与者计算模型,最后,“ predict”包含返回的预测。最后,我们取消嵌套“预测”:

newDat2 <- unnest(newDat2, predict)

   Participant Group Evidence    pc
   <fct>       <dbl>    <dbl> <dbl>
 1 part001         0    -2.47 0.215
 2 part001         0    -2.42 0.215
 3 part001         0    -2.37 0.216
 4 part001         0    -2.32 0.217
 5 part001         0    -2.27 0.217
 6 part001         0    -2.22 0.218
 7 part001         0    -2.17 0.219
 8 part001         0    -2.12 0.219
 9 part001         0    -2.07 0.220
10 part001         0    -2.02 0.221
# ... with 9,990 more rows

要获取与ggplot2兼容的所有参与者的数据集。

从那里开始,绘图代码相对容易。我正在使用geom_smooth计算每个组的摘要。有很多选择可以玩。

plot.newdat <- ggplot(data = newDat2, aes(x = Evidence, y = pc, color = factor(Group), group = Participant)) +
  geom_line(alpha = 0.2) +
  geom_smooth(aes(group = Group), method = glm, method.args = list(family = binomial))
print(plot.newdat)

enter image description here