¿Cómo reemplazar los valores de NA en una tabla * para las columnas seleccionadas *? data.frame, data.table

Hay muchos mensajes sobre cómo reemplazar los valores de NA. Soy consciente de que uno podría reemplazar NA en la siguiente tabla / marco con lo siguiente:

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

Pero, ¿y si quiero restringirlo solo a ciertas columnas? Déjame mostrarte un ejemplo.

Primero, comencemos con un conjunto de datos.

 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)) 

Lo que da:

  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, entonces solo quiero restringir el reemplazo a las columnas ‘a’ y ‘b’. Mi bash fue:

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

y:

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

Lo cual no funciona.

Mi bash de data.table, donde y<-data.table(x) , obviamente nunca va a funcionar:

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

Quiero pasar columnas dentro del argumento is.na, pero eso obviamente no funcionaría.

Me gustaría hacer esto en un data.frame y un data.table. Mi objective final es recodificar el 1: 2 a 0: 1 en ‘a’ y ‘b’ manteniendo ‘c’ tal como está, ya que no es una variable lógica. Tengo un montón de columnas, así que no quiero hacerlo una por una. Y, solo me gustaría saber cómo hacer esto.

¿Tienes alguna sugerencia?

Tu puedes hacer:

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

o mejor (en mi humilde opinión), use los nombres de las variables:

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

En ambos casos, 1:2 o c("a", "b") pueden reemplazarse por un vector predefinido.

Esto funcionará para su versión data.table :

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

Alternativamente, como señala David Arenburg a continuación, puede usar set (beneficio lateral: puede usarlo en data.frame o data.table ):

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

Esto ahora es trivial en tidyr con replace_na (). La función parece funcionar tanto para data.tables como para data.frames:

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

No estoy seguro si esto es más conciso, pero esta función también encontrará y permitirá el reemplazo de NA (o cualquier valor que desee) en las columnas seleccionadas de 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 } 

Para aplicarlo:

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

La función crea una matriz de las columnas y filas seleccionadas (coordenadas de celda) que cumplen los criterios de entrada (en este caso es.na == TRUE).

Para una columna específica, hay una 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 

Esto funciona bien para mi

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