3

可能是一个非常简单的问题,但我很难在 r 中解决这个问题。我有一个包含四个变量的数据集:ID(用于识别参与者)、类型(这次为 1 值)、决策(A 或 B)和反馈(0 或 1)。两个参与者的数据集如下所示:

ID   Type    Decision    Feedback
1     1       A           0
1     1       A           0
1     1       B           1
1     1       B           1
1     1       B           0
2     1       A           0
2     1       A           1
2     1       A           1
2     1       A           0
2     1       B           1
etc...

我想根据先前的反馈计算决策过程中的更改次数。换句话说,如果参与者选择 A 并收到负面反馈,她/他会再次选择 A(Stay)还是 B(Shift)。因此,对于一位参与者,我的代码如下:

Stay=0
Shift=0  

for(i in 2:length(mydf$Type)){  
    if(mydf$Decision[i] == "A" && mydf$Feedback[i-1]==1 && mydf$Decision [i-1] == "A" ){
    Stay= Stay+1
    }
    else if(mydf$Decision [i] == "B" && mydf$Feedback[i-1]==1 && mydf$Decision [i-1] == "B" ){
    Stay= Stay+1
    }
    else if(mydf$ Decision [i] == "A" && mydf$Feedback[i-1]==1 && mydf$Decision [i-1] == "B" ){
    Shift= Shift+1
    }
    else if(mydf$Decision [i] == "B" && mydf$Feedback[i-1]==1 && mydf$Decision [i-1] == "A" ){
    Shift= Shift+1
    }
}

但是,我的数据框包含 20 个参与者,我不知道如何扩展我的代码来获取每个参与者的停留和轮班次数(即,最后得到这样的东西):

#ID    Stay    Shift
#1     10      10
#2     16      4
#etc...

非常感谢您提前提供的帮助。

4

3 回答 3

3

最好ddplyplyr包中完成此操作(您必须安装它),它会根据其中一列拆分数据框,并对每一列进行一些分析,然后再重新组合成一个新的数据框。

首先,编写一个函数num.stay.shift,在给定数据框的单个子集的情况下计算您的逗留和移位值(在注释中解释):

num.stay.shift = function(d) {
    # vector of TRUE or FALSE for whether d$Feedback is 1
    negative.feedback = (head(d$Feedback, -1) == 1)
    # vector of TRUE or FALSE for whether there is a change at each point
    stay = head(d$Decision, -1) == tail(d$Decision, -1)
    # summarize as two values: the number that stayed when feedback == 1,
    # and the number that shifted when feedback == 1
    c(Stay=sum(stay[negative.feedback]), Shift=sum(!stay[negative.feedback]))
}

然后,使用ddply将该函数应用于数据框中的每个人,并按 ID 将其拆分:

print(ddply(tab, "ID", num.stay.shift))

在您显示的数据框的子集上,您最终会得到

#   ID Stay Shift
# 1  1    2     0
# 2  2    2     0
于 2013-03-27T15:39:25.517 回答
1

如何按 ID 和反馈进行很好的细分:

  library(data.table)
  X <- data.table(mydf, key="ID")

  X[, list(Dif=abs(diff(as.numeric(Decision))),  
          FB=head(Feedback, -1))
        , by=ID][,list(Shifted=sum(Dif), Stayed=length(Dif)-sum(Dif)), by=list(ID,FB)]

  #     ID FB Shifted Stayed
  #  1:  1  0       1      1
  #  2:  1  1       0      2
  #  3:  2  0       1      1
  #  4:  2  1       0      2

或者,如果您不希望按 分解Feedback,则更简洁:

X[ , {Dif=abs(diff(as.numeric(Decision))); 
     list(Shifted=sum(Dif), Stayed=length(Dif)-sum(Dif))}
  , by=list(ID)]

#      ID Shifted Stayed
# 1:  1       1      3
# 2:  2       1      3
于 2013-03-27T17:29:17.020 回答
1

embed正如@DavidRobinson's answer的评论中提到的,这是使用该函数的一个稍微复杂的替代方案。

d<-read.table(text="ID   Type    Decision    Feedback
1     1       A           0
1     1       A           0
1     1       B           1
1     1       B           1
1     1       B           0
2     1       A           0
2     1       A           1
2     1       A           1
2     1       A           0
2     1       B           1", header=TRUE)

do.call(rbind,
    by(d, d$ID, function(x) {
        f <- function(x) length(unique(x)) == 1
        stay <- apply(embed(as.vector(x$Decision), 2), 1, f)
        neg.feedback <- x$Feedback[1:nrow(x)-1] == 1
        c(Stay = sum(stay & neg.feedback), Shift = sum((! stay) & neg.feedback))
    })
)
#   Stay  Shift
# 1    2      0
# 2    2      0
于 2013-03-28T09:54:37.273 回答