2017-02-24 14 views
3

Unten ist der Code Ich habe jetztKopieren Listenelemente NA Listenelemente

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) 

Ich möchte einen Weg finden, kopieren Sie in der Liste Elemente zu füllen, die nicht eine NA mit dem Stand der Elemente Inhalt enthält, so dass jedes Listenelement ausgefüllt wird. Element 1-5 enthält die Matrix in Element 1 und 6-8 enthält die Matrix in Element 6. Ich kann dieses Problem einrichten, ohne dass NAs als Elemente verwendet werden, die kopiert werden sollen (if Verwenden von NULL oder etwas anderes hilft der Lösung).

Vielen Dank im Voraus für einen Rat.

Antwort

3

Sie Reduce Funktion mit accumulate Modus verwenden können (möglicherweise nicht auf sehr große Daten):

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

Das ist eine wirklich elegante Lösung war, danke. Es funktioniert ziemlich schnell für ein paar tausend Elemente. –

+0

Gern geschehen. Froh, dass es an deinem echten Fall funktioniert! – Psidom

5

is.na kann "Liste" s in Griff, genau die Art und Weise hier neeeded: Rückkehr TRUE bei ein EinzelNA:

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

Dieses Verhalten von is.na, auch, macht das Testen auf „Liste“ s effizient, wie es alle Elemente vermeidet Überprüfung mit (Länge! = 1).

Aufbau einer NA LOCF Funktionalität aus dieser:

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 

wir test_list Teilmenge:

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

Das ist sehr angenehm. Möglicherweise müssen die Namen jedoch zurückgesetzt werden. –

+0

@RichScriven: ..hätten keine Usecases einer Funktionalität gedacht, die 'c (TRUE, FALSE)' für 'is.na (liste (NA, c (NA, NA))) zurückgibt: .. :-). Sie haben Recht mit den "Namen", ich habe es gelassen, wie es für den Fall ist, dass eine gedruckte Information, welches Element übertragen wurde, nützlich sein könnte. –