2012-02-11 30 views
5

Tôi muốn viết một số mã sẽ lấy một khung dữ liệu nhất định, kiểm tra xem có cột nào bị thiếu hay không và nếu có, hãy thêm các cột bị thiếu 0 hoặc NA. Dưới đây là những gì tôi đã có:R: Tìm các cột bị thiếu, thêm vào khung dữ liệu nếu thiếu

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

Ngoài điểm này, tôi không thể tìm ra cách thêm vào cột bị thiếu ("x3") mà không mã hóa nó. Lý tưởng nhất, tôi muốn khung dữ liệu hoàn chỉnh mới có các cột theo cùng thứ tự như danh sách tên.

Bất kỳ ý tưởng nào? Mã hiện tại của tôi có thể bị bỏ qua, không vấn đề gì.

Trả lời

14

Dưới đây là một cách tiếp cận đơn giản

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

Bạn cũng có thể sử dụng 'Thiếu <- setdiff (nms, tên (df))' trong suốt hơn một chút. –

+1

@HongOoi - Đề xuất tốt. Đó là đẹp hơn nhiều, và tôi đã chỉnh sửa câu trả lời để bao gồm nó. Cảm ơn! –

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

Thanks guys, nhờ bạn tôi cố gắng làm điều đó với một danh sách các dataframes (Files) và một danh sách các 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 
    } 

} 
Các vấn đề liên quan