[英]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.