簡體   English   中英

如何將不同的功能應用於R中數據框中同一列的不同行?

[英]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中的計算

我可以按如下所示在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

R的示例數據

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'可以選擇,但是我不確定應該為TRUEFALSE提供什么條件。

期望的輸出

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_1Un_dt_2pred_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_1Un_dt_2pred_Local.Y的計算方式與后續行不同。

如果將其轉換為function ,則可以在較大數據集中的所有組上運行它。 或者,您可以將其嵌套在另一個for循環中,將組設置為該更大循環中的第一步。

雖然我(我相信大多數人)認為這是最好的,從遠離for循環時,可能的話,他們不完全的邪惡。 他們確實有自己的位置,我相信這里的問題是for循環是一個合理的解決方案的情況。

編輯:好的,似乎現在給出正確的輸出。 我沒有注意到行之間的一些差異。 讓我知道這對您如何工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM