ddply 不从按变量拆分的函数返回值

ddply not returning values from function split by variable

我正在使用 ddply 函数 (plyr) 按参与者 ID (pid) 分别计算某些内容。但是,出于某种原因,它没有返回 pid 的单独值,而是在所有 pid.

中返回相同的值

示例数据:

sdt<-c("Hit","Hit","Miss","Miss","False Alarm","Correct Reject","Correct Reject","Correct Reject",
   "Hit","Hit","Hit","Miss","False Alarm","False Alarm","False ALarm","Correct Reject")

pid<-c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2)

adhd_p<-data.frame(sdt,pid)

函数:

ddply(adhd_p, "pid", summarise,
  hitrate=(count(adhd_p$sdt=="Hit")[[2,2]])/((count(adhd_perf$sdt=="Hit")[[2,2]])+(count(adhd_p$sdt=="Miss")[[2,2]])),
  falsealarmrate=(count(adhd_p$sdt=="False Alarm")[[2,2]])/((count(adhd_p$sdt=="False Alarm")[[2,2]])+(count(adhd_p$sdt=="Correct Reject")[[2,2]])))

如果这有助于理解我在计算什么...参与者可以 "Hit"(肯定地回应目标)、"Miss"(不回应目标)、"Correct Reject"(不回应干扰因素),或 "False Alarm"(肯定回应干扰因素)。因此,"hitrate"是hits/hits+未命中的次数,"falsealarmrate"是错误的alarms/false警报+正确拒绝的次数。

我做错了什么?

感谢您的宝贵时间。

编辑:通过将代码编辑为

,上述问题很快解决了
 ddply(adhd_p, "pid", summarise,
  hitrate=(count(sdt=="Hit")[[2,2]])/((count(sdt=="Hit")[[2,2]])+(count(sdt=="Miss")[[2,2]])),
  falsealarmrate=(count(sdt=="False Alarm")[[2,2]])/((count(sdt=="False Alarm")[[2,2]])+(count(adhd_p$sdt=="Correct Reject")[[2,2]])))

我现在意识到我需要拆分两个变量而不是一个变量。但是添加时间变量:

time<-c(1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8)

并将其与其他合并

adhd_p<-data.frame(sdt,pid,time)

使新脚本产生 "subscript out of bounds" 错误。

ddply(adhd_p, .(pid,time), summarise,
  hitrate=(count(sdt=="Hit")[[2,2]])/((count(sdt=="Hit")[[2,2]])+(count(sdt=="Miss")[[2,2]])),
  falsealarmrate=(count(sdt=="False Alarm")[[2,2]])/((count(sdt=="False Alarm")[[2,2]])+(count(sdt=="Correct Reject")[[2,2]])))

有什么想法吗?

我没有深入研究为什么你做的是错的,但这里有一个可能有帮助的答案:

ddply(
  adhd_p, "pid", summarize, 
  hitrate=sum(sdt == "Hit") / sum(sdt %in% c("Hit", "Miss")),
  falsealarmrate=sum(sdt == "False Alarm") / sum(sdt %in% c("False Alarm", "Correct Reject"))
)

生产:

  pid hitrate falsealarmrate
1   1    0.50      0.2500000
2   2    0.75      0.6666667

您需要做的事情:

ddply(adhd_p, "pid", summarise,
  hitrate=(count(sdt=="Hit")[[2,2]])/((count(sdt=="Hit")[[2,2]])+(count(sdt=="Miss")[[2,2]])),
  falsealarmrate=(count(sdt=="False Alarm")[[2,2]])/((count(sdt=="False Alarm")[[2,2]])+(count(sdt=="Correct Reject")[[2,2]])))

为什么你需要这样做:

当您调用 ddply 时,该函数在 .data(在您的情况下为 adhd_p)作为本地名称空间工作。这类似于调用 attach(adhd_p);在不显式引用数据框的情况下调用列名仍会调用正确的列。

当您提供 summarise 参数时,该函数会根据提供的 id 列(在本例中为 pid)在本地命名空间中拆分向量。因此,如果您在没有像上面那样显式引用数据框的情况下引用列,则将使用对应于每个 pidsdt 列的部分进行计算。但是,如果您显式引用列和数据框(在您的情况下为 adhd_p$sdt),它只会从全局命名空间中提取整个向量,而不会适当地拆分它。

编辑:下面的代码既不那么混乱,如果缺少其中一个值也不会引发错误:

ddply(adhd_p, .(pid, time), summarise,
      hitrate=(sum(sdt=="Hit"))/(sum(sdt=="Hit"))+(sum(sdt=="Miss")),
      falsealarmrate=(sum(sdt=="False Alarm"))/(sum(sdt=="False Alarm"))+(sum(sdt=="Correct Reject")))