[英]How to apply different functions to different rows of same column in a data frame in R?
我正在嘗試使用以下方程式預測跟隨另一輛車的一輛車的速度:
請注意,第二個方程的分母中的Un(t)是一個錯字。 它實際上是增量。
哪里,
Un(t)=在時間t處跟隨車輛的速度,
CC8 = 1.765,CC9 = 1.04,
增量=時間步長= 1秒,
sn(t)=兩輛車之間的前保險杠到前保險杠的距離,
CC0 = 4.4,L_n-1 =領先車輛的長度,
請忽略uf,請注意3.6僅用於確保速度單位為km / hr。 另外,由於車輛位置由於速度而隨時間變化,因此估計這些位置也很重要。
我可以按如下所示在Excel中成功應用這些方程式:
注意:
Local.Y =從固定參考點(m)觀察到的跟隨車輛的縱向位置,
pred_Local.Y =預計跟隨車輛的縱向位置,
PrecVehLocalY =觀察到的引導車輛的縱向位置,
Un =跟隨車輛的觀測速度(m / s),
Un_dt_1 =使用第一個圖像中的第一個方程式預測的跟隨車輛的速度,
Un_dt_2 =使用第二個方程式預測的跟隨車輛的速度,
Un_dt = Un_dt_1和Un_dt_2的最小值Ln =引導車輛的實際長度= L_n-1,
sn_minus_Ln =觀察到的跟隨車輛的前保險杠與領先車輛的后保險杠之間的距離; sn是從前到前的距離,
pred_sn_minus_Ln =預測的前后距離;
您可以看到預測變量的第一行使用之前一個時間步長中的觀察變量。 但是之后,連續的行僅使用預測變量。 我不知道如何在R中做同樣的事情? 請幫忙。 我想使用dplyr
。
structure(list(Local.Y = c(50.71994, 60.37412, 69.99005, 78.60745
), Un = c(9.48762, 9.93521, 8.9674, 8.33772), PrecVehLocalY = c(70.19624,
78.50749, 86.49717, 93.4731), Ln = c(3.9019, 3.9019, 3.9019,
3.9019), sn_minus_Ln = c(15.5744, 14.23147, 12.60522, 10.96375
)), row.names = c(NA, 4L), class = "data.frame", .Names = c("Local.Y",
"Un", "PrecVehLocalY", "Ln", "sn_minus_Ln"))
請不要關閉這個問題。 我嘗試使用以下代碼,但僅適用於第一行:
df %>%
mutate(Un_dt_1 = lag(Un)*3.6 + 3.6*(1.765+(1.765-1.04)*lag(Un)*3.6/80))
'ifelse'可以選擇,但是我不確定應該為TRUE
和FALSE
提供什么條件。
structure(list(Local.Y = c(50.71994, 60.37412, 69.99005, 78.60745
), Un = c(9.48762, 9.93521, 8.9674, 8.33772), PrecVehLocalY = c(70.19624,
78.50749, 86.49717, 93.4731), Ln = c(3.9019, 3.9019, 3.9019,
3.9019), sn_minus_Ln = c(15.5744, 14.23147, 12.60522, 10.96375
), pred_Local.Y = c(NA, 57.624865, 69.5024275, 80.13921125),
pred_sn_minus_Ln = c(NA, 16.980725, 13.0928425, 9.43198875
), Un_dt_1 = c(NA, 41.62375297, 47.89427328, 53.12221615),
Un_dt_2 = c(NA, 40.22784, 45.29061, 31.294233), Un_dt = c(NA,
40.22784, 45.29061, 31.294233)), .Names = c("Local.Y", "Un",
"PrecVehLocalY", "Ln", "sn_minus_Ln", "pred_Local.Y", "pred_sn_minus_Ln",
"Un_dt_1", "Un_dt_2", "Un_dt"), row.names = c(NA, 4L), class = "data.frame")
我希望可以使用data.table
包(我的個人選擇,當然不是唯一的方法)來幫助您入門:
library( data.table )
setDT( df )
df[ , Un_dt_1 := shift( Un, n = 1L, type = "lag" ) * 3.6 +
3.6 * ( 1.765 + ( 1.765 - 1.04 ) *
shift( Un, n = 1L, type = "lag" ) *
3.6 / 80 )
]
df[ , Un_dt_2 :=
3.6 * ( shift( sn_minus_Ln, n = 1L, type = "lag" ) - 4.4 ) / 1
]
請注意,使用shift
函數將引用沿type
指定的方向偏移一定數量的行n
(默認為1)(“滯后”向上,“前導”向下)。 此處輸入的值實際上是默認值,因此您可以省略它們,但是為了完整起見,我希望將它們包括在內。
我認為這里使用的方法適用於您在電子表格中顯示的所有列。 如果您需要通過分組變量來應用內容,則需要以下內容:
df[ , output_column := function(x), by = group ]
其中function
是您要應用的函數, x
是該函數的輸入列,而group
是具有唯一組標識符的列。
編輯以回應OP的評論:沒有理由您不能向計算中添加更多變量,也不能將已經計算出的引用變量添加到新的計算中。 例如, Un_dt
依賴於上面我在其中包括計算的兩列,因此在下一步中請分別引用它們:
df[ , Un_dt := pmin( Un_dt_1, Un_dt_2 ) ]
(添加一個單獨的答案,因為我是從頭開始的)
我很高興現在能更好地理解您的問題,它肯定比我最初想到的要復雜得多。
鑒於您的計算需要按順序進行,因此這是一種完全不同的解決方法。 因為涉及到這樣的序列(即,對於每個計算而言,首先完成之前的計算很重要),所以我認為最好的方法是使用for
循環。 與隨后的運行相比,這還允許在第一次運行時為Un_dt_1
, Un_dt_2
和pred_Local.Y
指定不同的計算:
for( i in ( seq_len( nrow(df)-1 ) + 1 ) ) {
if( i <= 2L ) {
df$Un_dt_1[i] <- df$Un[i-1] * 3.6 +
3.6 * ( 1.765 + ( 1.765 - 1.04 ) *
df$Un[1] * 3.6 / 80 ) * 1
df$Un_dt_2[i] <- 3.6 * ( df$sn_minus_Ln[i-1] - 4.4 ) / 1
} else {
df$Un_dt_1[i] <- df$Un_dt[i-1] +
3.6 * ( 1.765 + ( 1.765 - 1.04 ) *
df$Un_dt[i-1] / 80 ) * 1
df$Un_dt_2[i] <- 3.6 * ( df$pred_sn_minus_Ln[i-1] - 4.4 ) / 1
}
df$Un_dt[i] <- pmin( df$Un_dt_1[i], df$Un_dt_2[i] )
if( i <= 2 ) {
df$pred_Local.Y[i] <- df$Local.Y[i-1] +
0.5 * ( ( df$Un_dt[i] + df$Un[i-1] ) / 3.6 ) * 1
} else {
df$pred_Local.Y[i] <- df$pred_Local.Y[i-1] +
0.5 * ( ( df$Un_dt[i] + df$Un_dt[i-1] ) / 3.6 ) * 1
}
df$pred_sn_minus_Ln[i] <- df$PrecVehLocalY[i] - df$pred_Local.Y[i] - df$Ln[i]
}
請注意,開始循環的seq_len
調用將返回從2開始的所有值,升至幀末尾。 然后將第2行視為一種特殊情況,其中Un_dt_1
, Un_dt_2
和pred_Local.Y
的計算方式與后續行不同。
如果將其轉換為function
,則可以在較大數據集中的所有組上運行它。 或者,您可以將其嵌套在另一個for
循環中,將組設置為該更大循環中的第一步。
雖然我(我相信大多數人)認為這是最好的,從遠離for
循環時,可能的話,他們不完全的邪惡。 他們確實有自己的位置,我相信這里的問題是for循環是一個合理的解決方案的情況。
編輯:好的,似乎現在給出正確的輸出。 我沒有注意到行之間的一些差異。 讓我知道這對您如何工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.