2014-04-06 3 views
3

모든 R 전문가가 다음을 수행하는 더 빠른 방법을 제공 할 수 있습니까? 내 코드는 작동하지만 30,000- [열] - 12 - [행] 데이터 프레임을 수행하는 데 1 분이 걸린다. 감사!R 데이터 프레임에서 누락 된 열을 빠르게 채울 수 있습니다.

sync.columns = function(old.data, new.colnames) 
    { 
     # Given a data frame and a vector of column names, 
     # makes a new data frame containing exactly the named 
     # columns in the specified order; any that were not 
     # present are filled in as columns of zeroes. 

     if (length(new.colnames) == ncol(old.data) && 
      all(new.colnames == colnames(old.data))) 
     { 
     old.data # nothing to do 
     } 
     else 
     { 
     m = matrix(nrow=nrow(old.data),ncol=length(new.colnames)) 

     for (t in 1:length(new.colnames)) 
     { 
      if (new.colnames[t] %in% colnames(old.data)) 
      { 
      m[,t] = old.data[,new.colnames[t]] # copy column 
      } 
      else 
      { 
      m[,t] = rep(0,nrow(m)) # fill with zeroes 
      } 
     } 
     result = as.data.frame(m) 
     rownames(result) = rownames(old.data) 
     colnames(result) = new.colnames 
     result 
     } 
    } 

어쩌면 무엇인가 cbind가 있습니까?

답변

3

다소 빠른 것 같습니다. 먼저 제로 가득 data.frame을 만든 다음 만이 이전 데이터에서 찾을 수있는 대체 :

sync.columns <- function(old.data, new.colnames) { 
    M <- nrow(old.data) 
    N <- length(new.colnames) 
    rn <- rownames(old.data) 
    cn <- new.colnames 
    new.data <- as.data.frame(matrix(0, M, N, dimnames = list(rn, cn))) 
    keep.col <- intersect(cn, colnames(old.data)) 
    new.data[keep.col] <- old.data[keep.col] 
    new.data 
} 

M <- 30000 
x <- data.frame(b = runif(M), i = runif(M), z = runif(M)) 
rownames(x) <- paste0("z", 1:M) 
system.time(y <- sync.columns(x, letters[1:12])) 
# user system elapsed 
# 0.031 0.010 0.043 

head(y) 
# a   b c d e f g h   i j k l 
# z1 0 0.27994248 0 0 0 0 0 0 0.3785181 0 0 0 
# z2 0 0.75291520 0 0 0 0 0 0 0.7414294 0 0 0 
# z3 0 0.07036461 0 0 0 0 0 0 0.1543653 0 0 0 
# z4 0 0.40748957 0 0 0 0 0 0 0.5564374 0 0 0 
# z5 0 0.98769595 0 0 0 0 0 0 0.4277466 0 0 0 
# z6 0 0.82117781 0 0 0 0 0 0 0.2034743 0 0 0 

편집 : 아래의 영업 이익과 의견을 다음, 여기에 매트릭스 버전 :

sync.columns <- function(old.data, new.colnames) { 
    M <- nrow(old.data) 
    N <- length(new.colnames) 
    rn <- rownames(old.data) 
    cn <- new.colnames 
    new.data <- matrix(0, M, N, dimnames = list(rn, cn)) 
    keep.col <- intersect(cn, colnames(old.data)) 
    new.data[, keep.col] <- old.data[, keep.col] 
    new.data 
} 

x <- t(as.matrix(x)) # a wide matrix 
system.time(y <- sync.columns(x, paste0("z", sample(1:50000, 30000)))) 
# user system elapsed 
# 0.049 0.002 0.051 
+0

감사합니다.이 기능을 사용하면 120 초가 아닌 25 초가됩니다. 1 초 또는 2 초 정도의 데이터를 원했습니다 (그 크기의 데이터 세트에서 read.csv를 수행하는 것과 비교할 수 있습니다). 다른 아이디어는 있습니까? –

+0

왜 25 초입니까? 내 예제는 40 밀리 초 밖에 걸리지 않습니다. 그 밖의 무엇을 알아야합니까? 어쩌면 우리에게'str (old.data)'를 보여줄지도 모른다. – flodel

+0

D' oh! 광산은 12 광폭 × 30000 광각이 아니며 광폭은 30000 광각 × 12 광속입니다. 미안합니다. 나는 여러 버전의 프로그램을 가지고 매트릭스를 돌렸다. 이제 구현을 보여 주었으므로 나중에 다시 돌려 보도록 유혹되었습니다! (도움이되지 않을 수도 있습니다. 왜냐하면 열보다는 행을 동기화해야하기 때문입니다.) 일반적으로 많은 수의 열이 많은 수의 열보다 잘 작동합니까? –

관련 문제