2016-11-22 22 views
1

我在Excel中有一個計算示例,我需要將其轉換爲R代碼以獲得更大的數據集。將Excel公式轉換爲使用上一行結果的R代碼

我的數據應該是這樣的:

time value cum_value floor scaled_time 
0 0  0   0  0 
1 1  1   1  1 
2 0.975 1.975  1  1 
3 0.95 2.925  3  2.038961039 
4 0.925 3.85  4  3.098982099 
5 0.9 4.75  5  4.185278042 
6 0.875 5.625  6  5.302030016 
7 0.85 6.475  7  6.453196107 

凡「標度的時間」列已在Excel中使用這種類型的公式被計算(例如示出爲6行):

=scaled_time5+((floor6-floor5)/((cum_value6-floor5)/(time6-scaled_time5))) 

因爲這是指先前行中的單元格,所以我無法在R中對此進行編碼。

這就是我迄今爲止所使用的(使用data.tableshift f結:

DF$Scaled_Time=shift(DF$Scaled_Time, 1L, "lag")+ 
    ((DF$Floor-shift(DF$Floor,1L,"lag"))/ 
     ((DF$Cum_Value-shift(DF$Floor,1L,"lag"))/ 
      (DF$Time-shift(DF$Scaled_Time, 1L, "lag")))) 

這並不工作,以及與此錯誤出現:

Error in `$<-.data.frame`(`*tmp*`, "Scaled_Time", value = numeric(0)) : 
    replacement has 0 rows, DF has 2246400 
In addition: Warning messages: 
1: In shift(DF$Floor, 1L, "lag") : NAs introduced by coercion 
2: In shift(DF$Floor, 1L, "lag") : NAs introduced by coercion 
+0

不應該'cum_value [3]'是'2.925'?以下所有內容都少於'1'? – DaveTurek

+0

是的,你是對的 - 我沒有正確複製數據列。我現在要修改。謝謝。 – sym246

回答

2

可以使用shift功能從data.table

df$result = 2.038961 
df[, result := shift(result)+((floor-shift(floor))/((cum_value-shift(floor))/(time-shift(result)))) ] 
+1

由於'shift(result)'值始終爲2.038961,因此不會使用這些行進行更新。因此,使用這種方法得到的結果是:'NA 3.098982 3.730983 4.476523 5.402377'而不是'2.038961 3.098982 4.185278 5.302030 6.453196'。 – sym246

1

使用dplyr您可以通過延遲獲得前值:

library(dplyr) 

我重新創建數據框:

vv <- data.frame(time=c(3,4,5,6,7), 
      value=c(0.95,0.925,0.9,0.875,0.85), 
      cum_value=c(3.925,4.85,5.75,6.625,7.475), 
      floor=c(3,4,5,6,7), 
      scaled_time=c(2.038961039,3.098982099,4.185278042,5.302030016,6.453196107)) 

下面是一個簡單的計算,你可以用你的,而不是:

time +((floor val UE-以前的本底值)/(cum_value在先的本底值)) 將被寫成:

> vv %>% mutate(V4=time+((floor-lag(floor,1))/(cum_value-lag(floor,1)))) 
    time value cum_value floor scaled_time  V4 
1 3 0.950  3.925  3 2.038961  NA 
2 4 0.925  4.850  4 3.098982 4.540541 
3 5 0.900  5.750  5 4.185278 5.571429 
4 6 0.875  6.625  6 5.302030 6.615385 
5 7 0.850  7.475  7 6.453196 7.677966 

如果我沒有錯過任何括號你原來的公式中,它應該是這樣的:

vv %>% mutate(V=lag(scaled_time,1)+ 
         ((floor-lag(floor,1))/ 
           ((cum_value-lag(floor,1))/(time-lag(scaled_time,1))) 
         ) 
       ) 

但是,事實證明,scaled_time應該是輸出,第一行將被初始化爲0(未計算)。所以其中一個選項是循環。

編輯:For循環解決方案

雖然去環路作爲最後的選擇,這是小dataframes的情況下,快速的解決方案:

vv$scaled_time <- 0 

for (i in 2: nrow(vv)) 
{ 
vv$scaled_time[i]= vv$scaled_time[i-1]+ 
       ((vv$floor[i]-vv$floor[i-1])/((vv$cum_value[i]-vv$floor[i-1])/(vv$time[i]-vv$scaled_time[i-1]))) 

} 
+0

在這兩個例子中,你都沒有使用'V'或'V4'這列的前一個值,這是我的公式需要使用的。我擁有的'scaled_time'列是我期待的結果。在你的最終代碼示例中,最後將需要'(時滯(V,1))',這是行不通的(除非我錯過了某些東西)。 – sym246

+0

@ sym246如果我沒有錯過...... V的公式給出了你想要的在scaled_time中的相同值,所以它根據需要計算scales_time。 – OmaymaS

+0

是的,但您正在使用'scaled_time'列來實現此目的。這是輸出的一個例子,所以它不能用於獲取它。在我的數據集中,我沒有'scaled_time'列,只需要使用前4列。 – sym246