簡體   English   中英

通過數據幀迭代R效率

[英]R efficiency iterating through dataframes

我正在使用大型數據集,可以將其稱為data ,並希望創建一個新列,可以基於某些列data$input將其命名為data$results 結果基於某些條件的if / then邏輯,所以我最初的方法是:

for (rows in data) {
    data$results <- if(data$results == "1" | data$results== "2") {
        trueAnswer
    } else {
        falseAnswer
    }
}

對於大數據幀,此過程可能需要幾個小時才能運行。 但是,如果我將數據子集化為僅包含data $ results為1或2的條目,而又不包含true的條目的數據幀,則可以將trueAnswer應用於一個數據幀,將falseAnswer應用於另一個數據幀。 然后,我可以重新綁定數據幀。 這種方法只需要幾分鍾。

為什么后者使用子集的方法要快得多? 在這種情況下,此過程將應用於許多不同的數據集,因此前一種方法太慢而無法實用。 我只是想了解導致第一種方法效率不足的原因。

始終建議提供一個完全可復制且最少的示例數據示例 這樣,我們可以根據您的樣本數據提供特定的幫助。

在很多情況下,可以避免在R中使用顯式的for循環,而是可以使用優化的矢量化操作。 例如ifelse是這樣的向量化函數。

通常, dplyr語法如下所示:

library(dplyr);
library(magrittr);
data %>%
    mutate(results = ifelse(input == 1 | input == 2, "1 or 2", "Neither 1 nor 2"))

更新資料

要查看ifelse是如何矢量化的,請看一下?ifelse

值:

一個與“測試”具有相同長度和屬性(包括尺寸和“類”)的向量,並且數據值來自“是”或“否”。 [...]

因此,換句話說,如果ifelse評估100個條件,則返回對象的長度為100。

這可能導致以下可能令人驚訝/意外的結果:

ifelse(c(TRUE), c(100, 200), c(300, 400))
#[1] 100

返回對象是c(100, 200)元素1,因為邏輯條件的長度為1。

ifelse(c(TRUE, TRUE, TRUE), c(100, 200), c(300, 400))
#[1] 100 200 100

返回對象的長度為3,因為邏輯條件的長度為3; 由於c(100, 200)只有兩個元素,因此R需要回收條目。

R效率是圍繞矢量而不是循環設計的。 很少(盡管確實會發生)for或while循環是解決問題的最佳方法。 對於您的情況,最好使用if / else的向量化版本:ifelse。 它需要一個測試向量(例如, result %in% 1:2 )和兩個可能的響應向量,具體取決於測試結果。 所有這些必須具有相同的長度。 當您給出長度為1的答案時,它將擴展到適當的長度,否則會出現錯誤。 在這里,它看起來像這樣:

data$results <- ifelse(results %in% 1:2, trueAnswer, falseAnswer)

暫無
暫無

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

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