假设我有一个包含以下参数的数据框
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)
}
答案 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 ),在循环之后,您需要裁剪矩阵以删除尾随的空行。