2013-01-22 219 views
4

我希望有人能幫我弄清楚如何編寫一個if-else語句來處理我的數據集。我有樹木年增長率的數據。我需要計算一年中增長率是否下降了50%以上。我無法應用ifelse語句來計算我的最終字段。我是比較新的R,所以我的代碼很可能不是很有效,但這裏是我到目前爲止有一個例子: 有關示例數據集,Ifelse語句在R中的數據框

test<-data.frame(year=c("1990","1991","1992","1993"),value=c(50,25,20,5)) 
    year value 
1 1990 50 
2 1991 25 
3 1992 20 
4 1993  5 

我再計算出當年的區別與前一年的增長(「值」):

test[-1,"diff"]<-test[-1,"value"]-test[-nrow(test),"value"] 
    year value diff 
1 1990 50 NA 
2 1991 25 -25 
3 1992 20 -5 
4 1993  5 -15 

,然後計算了每個年增長的50%將是:

test$chg<-test$value * 0.5 
    year value diff chg 
1 1990 50 NA 25.0 
2 1991 25 -25 12.5 
3 1992 20 -5 10.0 
4 1993  5 -15 2.5 

我再嘗試使用ifelse聲明計算一個字段「突變」,當從一年下降到下一個大於50%時,該字段將是「1」。這是我想使用的代碼,但我不知道如何正確地從上年引用「CHG」字段,因爲我得到一個錯誤(下面複製):

test$abrupt<-ifelse(test$diff<0 && abs(test$diff)>=test[-nrow(test),"chg"],1,0) 
Warning message: 
In abs(test$diff) >= test[-nrow(test), "chg"] : 
longer object length is not a multiple of shorter object length 
> test 
    year value diff chg abrupt 
1 1990 50 NA 25.0  NA 
2 1991 25 -25 12.5  NA 
3 1992 20 -5 10.0  NA 
4 1993  5 -15 2.5  NA 

測試當我剛剛分配了幾個數字時,類似的ifelse語句的工作方式就起作用了,但我不確定如何在數據框的上下文中使其工作。這裏正在它的一個例子短短值:

prevyear<-50 
curryear<-25 
chg<-prevyear*0.5 
> chg 
[1] 25 
> diff<-curryear-prevyear 
> diff 
[1] -25 
> abrupt<-ifelse(diff<0 && abs(diff)>= chg,1,0) 
> abrupt 
[1] 1 

如果有人可以幫助我弄清楚如何申請一個類似的ifelse語句來我的數據幀我將不勝感激!感謝您提供任何幫助。

謝謝你, 凱蒂

+0

在一個不相關的音符,有沒有寫這條線的另一種方式代碼 'test [-1,「diff」] < - test [-1,「value」] - test [-nrow(test),「value」]' –

回答

3

我會改變,你就會把使其排隊與diff要比較它:

test$chg[2:nrow(test)] <- test$value[1:(nrow(test)-1)] * 0.5 

然後,糾正你喜歡藍色魔導師邏輯運算符說:

test$abrupt<-ifelse(test$diff<0 & abs(test$diff)>=test$chg,1,0) 

,你有你的結果:

year value diff chg abrupt 
1 1990 50 NA NA  NA 
2 1991 25 -25 25.0  1 
3 1992 20 -5 12.5  0 
4 1993  5 -15 10.0  1 

此外,您可能會發現功能diff有所幫助:而不是這樣做:

test[-1,"value"]-test[-nrow(test),"value"] 

你可以做

diff(test$value) 
+0

謝謝大家回答我的問題。我標記了喬納森的答案,因爲這很好地解決了這個問題,但是感謝藍魔師指出我的錯誤陳述中的錯誤,並向阿倫展示了一種計算兩年值之間差異的更有效方法。再次感謝大家的幫助。 – user1913921

+0

我有一個後續問題。我現在試圖將喬納森的答案中的代碼應用於我的真實數據。實際數據中存在一些合法的「NA」值,因此「abs」語句在我的最終ifelse語句中不起作用。所以,我嘗試使用這個代碼: – user1913921

4

,因爲這兩個向量比較abs(test$diff) >= test[-nrow(test),"chg"]有不同的長度它拋出一個警告。此外,對於邏輯和,當您應該使用&(它是矢量化的:它在兩個矢量上按元素運算並返回相同長度的矢量)時,您正在使用&&(它只給出一個TRUE或FALSE)。試試這個:

test$abrupt<-ifelse(test$diff<0 & abs(test$diff)>=test$chg,1,0) 
+2

這比較錯誤的'diff'和'chg',除非'chg'的計算方法不同(請參閱我的答案),但+1顯示錯誤的來源。 –

+0

我有一個後續問題:我試圖將Jonathan的代碼應用於我的真實數據。我在我的真實數據中有合法的「NA」值,這會阻止最終的ifelse語句中的「abs」函數運行。當我嘗試將聲明應用於真實數據時,出現以下錯誤:abs(test $ diff)中的錯誤: 數學函數的非數字參數。有沒有人在本聲明中使用「abs」函數時如何忽略「NA」值?我想我需要使用na.omit,但我不確定它在哪裏適合ifelse聲明。謝謝你的幫助! Katie – user1913921

+0

@ user1913921'abs(NA)'正確地爲我返回'NA'。什麼是'class(test $ diff)'和'mode(test $ diff)'? –