2013-03-21 49 views
0

我已經創建了下面的簡單函數的R值多行:應用功能,使用多行

fun <- function(a,b,c,d,e){b+(c-a)*((e-b)/(d-a))} 

,我想這個功能適用於data.frame,看起來像:

> data.frame("x1"=seq(55,75,5),"x2"=round(rnorm(5,50,10),0),"x3"=seq(30,10,-5)) 
    x1 x2 x3 
1 55 51 30 
2 60 45 25 
3 65 43 20 
4 70 57 15 
5 75 58 10 

我想申請fun到每個單獨的行來創建一個新的變量x4,但現在來了困難的部分(對我來說至少..):對於參數d和e我想要使用值x2和來自下一行的。因此,對於示例的第一行將意味着:fun(a=55,b=51,c=30,d=45,e=25)。我知道我可以使用mapply()來爲每一行應用一個函數,但我不知道如何告訴它應該使用下一行中的某些值,或者我是否應該尋找與mapply()不同的方法?

非常感謝提前!

+0

怎麼樣的最後一排? 'a = 75,b = 58,c = 10',d和e是? – Arun 2013-03-21 16:05:42

+0

好點!假設'd = X2 + 2(so 60)'和'e = 0'。 (對於我的項目,最後一行實際上並不感興趣) – Rob 2013-03-21 16:12:53

回答

6

使用mapply,但將第四列和第五列移動一行。您可以手動完成,或使用taRifx::shift

> dat 
    x1 x2 x3 
1 55 25 30 
2 60 58 25 
3 65 59 20 
4 70 68 15 
5 75 43 10 
library(taRifx) 
> shift(dat$x2) 
[1] 58 59 68 43 25 
> mapply(dat$x1, dat$x2, dat$x3, shift(dat$x2), shift(dat$x3) , FUN=fun) 
[1] 25.00000 -1272.00000 719.00000 -50.14815 26.10000 

如果你想最後一排是NA,而不是包裝,使用wrap=FALSE,pad=TRUE

> shift(dat$x2,wrap=FALSE,pad=TRUE) 
[1] 58 59 68 43 NA 
+0

對不起,但是'shift(dat $ x2)'(它與OP的數據相同的x2)與你所顯示的相同嗎? – Arun 2013-03-21 16:23:03

+0

非常感謝@Ari這樣做!爲了解決最後一行的問題,我改變了代碼如下:'dat $ x4 < - mapply(dat $ x1,dat $ x2,dat $ x3,c(shift(dat $ x2,wrap = F),dat $ x2 [length(dat $ x2)] + 2),c(shift(dat $ x3,wrap = F),0),FUN = fun)' – Rob 2013-03-21 16:30:37

+1

@Arun我沒有意識到OP在他的隨機值data.frame構造,而不指定'set.seed()',這可能是乍一看它與OP相同的原因。增加了我的'dat'的樣子。 – 2013-03-21 17:59:43