可能是一个非常简单的问题,但我很难在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(停留)或B(转移)。所以我的代码对于一位参与者来说如下:
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...
非常感谢您的帮助。
答案 0 :(得分:3)
最好使用plyr包中的ddply
(您必须安装它),根据其中一个列拆分数据框并对每个列进行一些分析,在重新组合成新数据框之前。
首先,编写一个函数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
答案 1 :(得分: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
答案 2 :(得分:1)
这是使用embed
函数的稍微有点替代方法,正如@ DavidRobinson回答的评论中提到的那样。
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