2013-03-27 47 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 
相關問題