2013-01-22 217 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)'? –