2013-03-27 49 views
3

可能是一个非常简单的问题,但我很难在r中解决这个问题。 我有一个包含四个变量的数据集:ID(用于识别参与者),Type(此次具有1个值),Decision(A或B)和Feedback(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

你可以发布'dput(head(mydf,50))'的结果吗?这会创建数据框的前50行的可重复版本,并使它更容易回答? – 2013-03-27 15:25:44

+0

这些反馈因素如何与他们留在A或B中? – Chase 2013-03-27 15:33:44

+0

对于你所示的例子,对于'ID = 1',你能解释'stay'和'shift'是什么吗? – Arun 2013-03-27 15:38:18

回答

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用于使用-1与'head'和'tail'。我用'embed'也有类似的答案,但是这个更清晰。 – 2013-03-27 16:10:44

+0

@David Robinson非常快速的答复感谢。我需要一些时间来充分理解您的解决方案,因为结果似乎不正确。例如,在ID = 1中,有3次停留和1次班次。但我想,我现在可以弄清楚了。非常感谢!! – user2205323 2013-03-27 16:26:38

+1

@ user2205323:你说你只想在以前的反馈是'1'的情况下停留和转移(这不就是为什么你有代码'mydf $ Feedback [i-1] == 1'吗?)在这种情况下,我相信我给出的输出是正确的 – 2013-03-27 16:37:28

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 
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 
相关问题