2012-02-11 14 views
5

Me gustaría escribir un código que tomaría un marco de datos determinado, verifique si falta alguna columna y, de ser así, agregue las columnas faltantes llenas 0 o NA. Esto es lo que tengo:R: Encuentre las columnas faltantes, agregue al marco de datos si falta

> df 
    x1 x2 x4 
1 0 1 3 
2 3 1 3 
3 1 2 1 

> nameslist <- c("x1","x2","x3","x4") 
> miss.names <- !nameslist %in% colnames(df) 
> holder <- rbind(nameslist,miss.names) 
> miss.cols <- subset(holder[1,], holder[2,] == "TRUE") 

Más allá de este punto, no puedo encontrar la manera de poner en la columna que falta ("x3") sin codificar ella. Idealmente, me gustaría que el nuevo y completo marco de datos tenga columnas en el mismo orden que la lista de nombres también.

¿Alguna idea? Mi código actual puede ser ignorado, no hay problema.

Respuesta

14

Aquí es un enfoque sencillo

df <- data.frame(a=1:4, e=4:1) 
nms <- c("a", "b", "d", "e") # Vector of columns you want in this data.frame 

Missing <- setdiff(nms, names(df)) # Find names of missing columns 
df[Missing] <- 0     # Add them, filled with '0's 
df <- df[nms]      # Put columns in desired order 
# a b d e 
# 1 1 0 0 4 
# 2 2 0 0 3 
# 3 3 0 0 2 
# 4 4 0 0 1 
+1

También puede usar 'Missing <- setdiff (nms, names (df))' que es un poco más transparente. –

+1

@HongOoi - Buena sugerencia. Eso es mucho mejor, y he editado la respuesta para incluirlo. ¡Gracias! –

1
library(stringr) 
df <- data.frame(X1=1:4,X2=1:4,X5=1:4) 
>df 
    X1 X2 X5 
1 1 1 1 
2 2 2 2 
3 3 3 3 
4 4 4 4 
current <- as.numeric(str_extract(names(df),"[0-9]")) 
missing <-seq(min(current),max(current)) 

df[paste("X",missing[!missing %in% current],sep="")]<-0 

>df[,order(colnames(df))] 
    X1 X2 X3 X4 X5 
1 1 1 0 0 1 
2 2 2 0 0 2 
3 3 3 0 0 3 
4 4 4 0 0 4 
0

Gracias chicos, gracias a ti he logrado hacerlo con una lista de tramas de datos (archivos) y otra lista de COLNAMES (ncolunas).

for (i in serieI) { 
    if ((identical(colnames(Files[[i]]),ncolunas)) == FALSE) { 

     nms = ncolunas 
      df = Files[[i]] 
      aux = colnames(df) 
      aux1 = row.names(df) 

      Missing = setdiff(nms, colnames(df)) 

      serie = seq(1,length(Missing)) #creating indices 1-5 for loop 
      for (j in serie) { #loop to add colums with zeros 
       df = cbind(df,c(0)) 
      } 
      colnames(df) = c(aux,Missing) #updates columns names 

      df = df[,order(colnames(df))] #put colums into order 
      df = t(as.matrix(df))   #hanges into matrix 
      row.names(df) = aux1   #update lines' names 
      Files[[i]] = df    #updates object from list 
    } 

} 
Cuestiones relacionadas