2017-02-24 114 views
3

下面是我現在複製下拉列表元素來填充NA列表元素

set.seed(20) 
test_list <- list("1" = matrix(rnorm(100), 10, 10), 
        "2" = NA, 
        "3" = NA, 
        "4" = NA, 
        "5" = NA, 
        "6" = matrix(rnorm(100), 10, 10), 
        "7" = NA, 
        "8" = NA) 

我想找到一種方法來降低未包含NA與現有元素內容的列表元素複製代碼以便每個列表元素都將被填充。元素1-5將包含元素1中的矩陣,元素6-8中將包含元素6中的矩陣。我可以設置此問題,而不使用NA作爲應該複製的元素(if使用NULL或其他類似的東西有助於解決方案)。

非常感謝您的任何建議。

回答

3

可以使用Reduce功能與accumulate模式(可能無法工作在非常大的數據):

str(test_list) 
#List of 8 
# $ 1: num [1:10, 1:10] 1.163 -0.586 1.785 -1.333 -0.447 ... 
# $ 2: logi NA 
# $ 3: logi NA 
# $ 4: logi NA 
# $ 5: logi NA 
# $ 6: num [1:10, 1:10] 0.548 -0.226 1.217 0.701 0.912 ... 
# $ 7: logi NA 
# $ 8: logi NA 


fill_list <- Reduce(function(x, y) if(all(is.na(y))) x else y, test_list, acc = TRUE) 

str(fill_list) 
#List of 8 
# $ : num [1:10, 1:10] 1.163 -0.586 1.785 -1.333 -0.447 ... 
# $ : num [1:10, 1:10] 1.163 -0.586 1.785 -1.333 -0.447 ... 
# $ : num [1:10, 1:10] 1.163 -0.586 1.785 -1.333 -0.447 ... 
# $ : num [1:10, 1:10] 1.163 -0.586 1.785 -1.333 -0.447 ... 
# $ : num [1:10, 1:10] 1.163 -0.586 1.785 -1.333 -0.447 ... 
# $ : num [1:10, 1:10] 0.548 -0.226 1.217 0.701 0.912 ... 
# $ : num [1:10, 1:10] 0.548 -0.226 1.217 0.701 0.912 ... 
# $ : num [1:10, 1:10] 0.548 -0.226 1.217 0.701 0.912 ... 
+0

這是一個非常優雅的解決方案,謝謝。至少對於數千個元素來說,它的運行速度非常快。 –

+0

不客氣。很高興它適用於你的真實案例! – Psidom

5

is.na可以處理「列表」 S在,正好,這裏neeeded方式:在以下情況下返回TRUE一個NA

is.na(test_list) 
# 1  2  3  4  5  6  7  8 
#FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE 

is.na這種行爲,也使得測試「清單」 S有效,因爲它避免了檢查的任何元素上(長度!= 1)。

建設NA LOCF功能關閉此:

cummax((!is.na(test_list)) * seq_along(test_list)) 
#1 2 3 4 5 6 7 8 
#1 1 1 1 1 6 6 6 

我們子集test_list

test_list[cummax((!is.na(test_list)) * seq_along(test_list))] 
+0

這很令人愉快。可能需要重置名稱。 –

+0

@RichScriven:..我們不會想到對'is.na(list(NA,c(NA,NA)))':-)返回'c(TRUE,FALSE)'的函數的用例。你對「名稱」是正確的,我把它留在原來的位置,以防打印出的信息包含哪些元素可能是有用的。 –