Come sostituire i valori NA in una tabella * per le colonne selezionate *? data.frame, data.table

Ci sono molti post sulla sostituzione dei valori di NA. Sono consapevole che si potrebbe sostituire NA nella seguente tabella / frame con il seguente:

x[is.na(x)]<-0 

Ma cosa succede se voglio limitarlo solo a determinate colonne? Lascia che ti mostri un esempio.

Innanzitutto, iniziamo con un set di dati.

 set.seed(1234) x <- data.frame(a=sample(c(1,2,NA), 10, replace=T), b=sample(c(1,2,NA), 10, replace=T), c=sample(c(1:5,NA), 10, replace=T)) 

Che dà:

  abc 1 1 NA 2 2 2 2 2 3 2 1 1 4 2 NA 1 5 NA 1 2 6 2 NA 5 7 1 1 4 8 1 1 NA 9 2 1 5 10 2 1 1 

Ok, quindi voglio limitare la sostituzione alle colonne ‘a’ e ‘b’. Il mio tentativo è stato:

 x[is.na(x), 1:2]<-0 

e:

 x[is.na(x[1:2])]<-0 

Che non funziona

Il mio tentativo data.table, dove y<-data.table(x) , ovviamente non avrebbe mai funzionato:

 y[is.na(y[,list(a,b)]), ] 

Voglio passare colonne all’interno dell’argomento is.na ma ovviamente non funzionerebbe.

Mi piacerebbe farlo in un data.frame e un data.table. Il mio objective finale è ricodificare 1: 2 a 0: 1 in ‘a’ e ‘b’ mantenendo “c” come è, dato che non è una variabile logica. Ho un mucchio di colonne quindi non voglio farlo uno per uno. E vorrei solo sapere come fare questo.

Hai qualche suggerimento?

Tu puoi fare:

 x[, 1:2][is.na(x[, 1:2])] < - 0 

o meglio (IMHO), usa i nomi delle variabili:

 x[c("a", "b")][is.na(x[c("a", "b")])] < - 0 

In entrambi i casi, 1:2 c("a", "b") può essere sostituito da un vettore predefinito.

Questo funzionerà per la tua versione data.table :

 for (col in c("a", "b")) y[is.na(get(col)), (col) := 0] 

In alternativa, come indicato da David Arenburg di seguito, puoi utilizzare set (vantaggio laterale: puoi utilizzarlo sia su data.frame o data.table ):

 for (col in 1:2) set(x, which(is.na(x[[col]])), col, 0) 

Questo è ora banale in tidyr con replace_na (). La funzione sembra funzionare per data.tables così come data.frames:

 tidyr::replace_na(x, list(a=0, b=0)) 

Non sono sicuro se questo è più conciso, ma questa funzione troverà e consentirà la sostituzione di NA (o qualsiasi valore che ti piace) nelle colonne selezionate di un data.table:

 update.mat < - function(dt, cols, criteria) { require(data.table) x <- as.data.frame(which(criteria==TRUE, arr.ind = TRUE)) y <- as.matrix(subset(x, x$col %in% which((names(dt) %in% cols), arr.ind = TRUE))) y } 

Per applicarlo:

 y[update.mat(y, c("a", "b"), is.na(y))] < - 0 

La funzione crea una matrice delle colonne e delle righe selezionate (coordinate della cella) che soddisfano i criteri di input (in questo caso is.na == TRUE).

Per una colonna specifica, c’è un’alternativa con sapply

 DF < - data.frame(A = letters[1:5], B = letters[6:10], C = c(2, 5, NA, 8, NA)) DF_NEW <- sapply(seq(1, nrow(DF)), function(i) ifelse(is.na(DF[i,3]) == TRUE, 0, DF[i,3])) DF[,3] <- DF_NEW DF 

questo funziona bene per me

 DataTable DT = new DataTable(); DT = DT.AsEnumerable().Select(R => { R["Campo1"] = valor; return (R); }).ToArray().CopyToDataTable();