2013-07-08 25 views
2

假設我有幾行看起來像一個數據幀:如果語句中的R,與數據幀

 User Lab Score 
     A  1  5 
     A  2  6 
     A  4  7 
     B  1  3 
     B  3  4 
     C  2  5 

然後,對於實驗室1,我想除以5的分數,對於實驗室2 ,我想把分數除以8,對於實驗室3,我想將分數除以7,對於實驗室4,我想將得分除以9。 我該如何去做這件事?

+0

你想要的'之開關功能。請參閱'?switch'獲取更多信息 – Justin

回答

9

對於這樣的數據轉換任務,請使用ifelse,它是基於條件從不同結果中選擇的矢量化形式。

df$Score <- with(df, ifelse(Lab == 1, Score/5, 
        ifelse(Lab == 2, Score/8, 
        ifelse(Lab == 3, Score/7, Score/9)))) 

(這是假設你只有4個實驗室。)

+0

我會爲此+1,因爲OP沒有采取這種麻煩,而且正是所要求的。令人驚訝的是,我採取的非正統的「因素」方法比這更快。我不知道如果需要完成很多重新編譯,嵌套的'ifelse'語句會如何有效。 – A5C1D2H2I1M1N2O1R2T1

0

這可能是相當非正統的,但也可能是更容易比很多ifelse s到閱讀。 factor您的「實驗室」值,將除數指定爲labels,並按正常方式進行劃分。假設data.frame被稱爲 「是myDF」:

within(mydf, { 
    temp <- as.numeric(as.character(factor(Lab, levels=c(1, 2, 3, 4), 
             labels=c(5, 8, 7, 9)))) 
    Score <- Score/temp 
    rm(temp) 
}) 
# User Lab  Score 
# 1 A 1 1.0000000 
# 2 A 2 0.7500000 
# 3 A 4 0.7777778 
# 4 B 1 0.6000000 
# 5 B 3 0.5714286 
# 6 C 2 0.6250000 
2

這裏使用merge乾淨和普遍意義的解決方案。

dat1 <- data.frame(Lab=c(1,2,3,4), 
        coef = c(1/5,1/8,1/7,1/9)) 
dt.m <- merge(dat,dat1,all.x=TRUE) 
dt.m$coef[is.na(dt.m $coef)] <- 1 ## default value 
dtt <- transform(dt.m,newScore=Score*coef) 


    Lab User Score  coef newScore 
1 1 A  5 0.2000000 1.0000000 
2 1 B  3 0.2000000 0.6000000 
3 2 A  6 0.1250000 0.7500000 
4 2 C  5 0.1250000 0.6250000 
5 3 B  4 0.1428571 0.5714286 
6 4 A  7 0.1111111 0.7777778 

編輯如果你想獲得相同的順序,結構原始數據:

dtt[order(dtt$User),c('User','Lab','Score','newScore')] 
User Lab Score newScore 
1 A 1  5 1.0000000 
3 A 2  6 0.7500000 
6 A 4  7 0.7777778 
2 B 1  3 0.6000000 
5 B 3  4 0.5714286 
4 C 2  5 0.6250000 
+0

我想+1這個 - 我喜歡思考的線 - 但我不喜歡所得到的'data.frame'的順序與最初的'data.frame'不同。你能修改它以解決這個問題嗎? – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto我編輯我的答案。 – agstudy

+0

+1進行編輯。我會認爲在'merge'命令中加入'sort'會有所幫助,但它似乎沒有做任何事情! – A5C1D2H2I1M1N2O1R2T1