2015-12-18 17 views
9

Voglio convertire tutti gli 0 nelle matrici di una lista in NA. Ho trovato un modo per raggiungere questo obiettivo. Tuttavia, è troppo complesso e penso che ci dovrebbe essere un modo semplice come farlo. Ecco alcuni dati esempio:R: Un modo più semplice per cambiare gli 0 nella lista delle matrici in NA?

ABlue <- list("111.2012"=matrix(c(1, 0, 6, 0, 1, 0), 
          nrow = 1, byrow = T), 
      "112.2012"=matrix(c(6, 2, 2, 0, 3, 1), 
          nrow = 1, byrow = T), 
      "111.2011"=matrix(c(3, 2, 0, 0, 1, 9), 
          nrow = 1, byrow = T), 
      "112.2011"=matrix(c(1, 2, 0, 0, 7, 0), 
          nrow = 1, byrow = T)) 
CNTRYs <- c("USA", "GER", "UK", "IT", "CND", "FRA") 
ABlue <- lapply(ABlue , "colnames<-", CNTRYs) # gets names from Country list 

importante è che le matrici originali hanno già i nomi di paese come colnames, quindi sarebbe bello per abbinare con questa lista (ablue).

Ecco il modo in cui io uso fino ad ora:

ABlue.df<-data.frame(do.call("rbind",ABlue)) # two step approach to replace 0 with NA according to: "http://stackoverflow.com/questions/22870198/is-there-a-more-efficient-way-to-replace-null-with-na-in-a-list" 
ABlue.df.withNA <- sapply(ABlue.df, function(x) ifelse(x == 0, NA, x)) 
ABlueNA <- split(ABlue.df.withNA, 1:NROW(ABlue.df.withNA)) # is again a list (of vectors) 
names(ABlueNA) <- names(ABlue) # list with old names 
ABlueNAdf <- lapply(ABlueNA, function(x) as.data.frame(x)) # turned into list of dfs of one column 
ABlueNAdfT <- lapply(ABlueNAdf, function(x) t(x)) # transponed to list of dfs of one row and 206 cols 
ABlueNAdfTnam <- lapply(ABlueNAdfT , "colnames<-", CNTRYs) # gets names from Country list 
ABlueNAdfTnam <- lapply(ABlueNAdfTnam , "rownames<-", 1:NROW(ABlueNAdfTnam[1])) 
ABlue2 <- ABlueNAdfTnam 

idee su come ridurre le linee e la complessità? Grazie

Modifica: Voglio avere la stessa struttura dei dati originali!

risposta

17

È possibile utilizzare replace, in questo modo:

lapply(ABlue, function(x) replace(x, x == 0, NA)) 
# $`111.2012` 
#  USA GER UK IT CND FRA 
# [1,] 1 NA 6 NA 1 NA 
# 
# $`112.2012` 
#  USA GER UK IT CND FRA 
# [1,] 6 2 2 NA 3 1 
# 
# $`111.2011` 
#  USA GER UK IT CND FRA 
# [1,] 3 2 NA NA 1 9 
# 
# $`112.2011` 
#  USA GER UK IT CND FRA 
# [1,] 1 2 NA NA 7 NA 

Oppure, come ha suggerito @roland:

lapply(ABlue, function(x) {x[x == 0] <- NA; x}) 

Oppure, se si dispone di una dipendenza del tubo:

library(purrr) 
ABlue %>% map(~ replace(.x, .x == 0, NA)) 
+4

che fondamentalmente è 'lapply (ABlue, function (x) {x [x == 0] <- NA; x})'. – Roland

+0

È facile, grazie. I love SO :) –

+0

@ N.Varela, nessun problema. Grazie per aver pubblicato un esempio riproducibile oltre a mostrare i tentativi che hai già fatto. – A5C1D2H2I1M1N2O1R2T1

0

Noi può anche usare for.

for (i in 1:length(ABlue)) { 
    ABlue[[i]][ABlue[[i]]==0] <- NA 
} 

ABlue 
# $`111.2012` 
#  USA GER UK IT CND FRA 
# [1,] 1 NA 6 NA 1 NA 
# 
# $`112.2012` 
#  USA GER UK IT CND FRA 
# [1,] 6 2 2 NA 3 1 
# 
# $`111.2011` 
#  USA GER UK IT CND FRA 
# [1,] 3 2 NA NA 1 9 
# 
# $`112.2011` 
#  USA GER UK IT CND FRA 
# [1,] 1 2 NA NA 7 NA 

mi chiedo fare abbiamo tutte le altre funzioni per iterare su una lista, tranne lapply e for.