R数据框列比较没有for循环,复杂的情况

时间:2014-02-13 22:04:27

标签: r performance for-loop iteration transformation

假设我有一个包含以下参数的数据框

DATA< - data.frame(ROWID,ID1,NAME1,... IDn,NAMEn)

数据可能如下所示:

ROWID | ID1 | NAME1 | ID2 | NAME2 | IDn | NAMEn
001   | 001 | FAS   | 002 | MAS   | 999 | ZOO
002   | 003 | BIN   | 004 | DUN   | 998 | SOO

我有201列10k +行。我想要做的是重新整形这些数据,以便对于原始DATA中的每一行,我在后续数据帧中生成一组行。每行将由原始ROWID,IDa,NAMEa,IDb,NAMEb对组成,使得第一行与所有其他对匹配(99对包含ID1,98与ID2,依此类推)。对于每行,将产生每行的所有可能组合的大数据帧。结果如下:

ROWID1 | ID1 | NAME1 | ID2 | NAME2
ROWID1 | ID1 | NAME1 | ID3 | NAME3
...
ROWID1 | ID2 | NAME2 | ID3 | NAME3
...
ROWID2 | ID1 | NAME1 | ID2 | NAME2
ROWID2 | ID1 | NAME1 | ID3 | NAME3
...

我为此而制作的代码如下。它工作得很好,但只适用于较小的数据帧。完整的数据框架非常缓慢,我希望有其他方法可以使用我不知道的功能或其他功能加快速度。在此先感谢!!

DATA <- data.frame(as described above)
META <- data.frame(ROWID=numeric(0),ID1=numeric(0),
                   BUS1=character(0),ID2=numeric(0),BUS2=character(0))
for (i in 1:length(DATA$ROWID)) {
  SET <- data.frame(ROWID=numeric(0),ID1=numeric(0),
                   BUS1=character(0),ID2=numeric(0),BUS2=character(0))
  ROWID <- DATA[i,1]
       for (x in seq(3,ncol(DATA),2)) {
       for (y in seq(x,ncol(DATA),2)) {
             ID1 <- DATA[i,x-2]
             BUS1 <- DATA[i,x]
             ID2 <- DATA[i,y-2]
             BUS2 <- DATA[i,y]
             if (!is.na(BUS1) && !is.na(BUS2)) {
             NEW <- cbind(ROWID, ID1, BUS1, ID2, BUS2)
             SET <- rbind(SET, NEW)
                                    }
            }
         }
           META <- rbind(META, SET)
       }

1 个答案:

答案 0 :(得分:0)

这是我编写它的方法,其中包括我作为注释编写的所有3个优化。另外,小心!你的代码在处理列时遇到了一些错误......我希望也能解决这个问题。

require('compiler')
enableJIT(3)
DATA2 = as.matrix(DATA)
META2 <- matrix(character(),ncol=5,nrow=(nrow(DATA2)*(ncol(DATA2)-2)^2/2)) # you want a matrix instead of a data.frame, and you want to pre-allocate its size
colnames(META2) = c("ROWID","ID1","BUS1","ID2","BUS2")
k=0
for (i in 1:nrow(DATA2)) {
  for (x in seq(3,ncol(DATA2)-2,2)) {
    for (y in seq(x+2,ncol(DATA2),2)) {
      k=k+1
      META2[k,] = c(DATA2[i,1],DATA2[i,x-1], DATA2[i,x], DATA2[i,y-1], DATA2[i,y]) # no need to use temporary variables
    }
  }
}
META2 = as.data.frame(META2)  # converting back to data.frame
META2$BUS1 = as.numeric(META2$BUS1)
META2$BUS2 = as.numeric(META2$BUS2)

我会让你自己处理BUS1或BUS2为NA的情况 - 基本上,你需要添加这些行(并且增加变量 k ),在循环之后,您需要裁剪矩阵以删除尾随的空行。