【发布时间】:2017-09-12 16:29:01
【问题描述】:
我需要一些智慧!
我有两个数据框,比如:
test1 <- data.frame( let = replicate( 100, paste(sample(LETTERS[1:12] , 3 ) , collapse ="") ) , num = sample( 1:500 , 100 , replace = FALSE ))
test2 <- data.frame( let = replicate( 100, paste(sample(LETTERS[13:26] , 4 ) , collapse ="") ) , num = sample( 1:500 , 100 , replace = FALSE ))
head( test1 )
# let num
# 1 KDA 430
# 2 IHB 41
# 3 GAB 473
# 4 HKJ 335
# 5 LCK 261
# 6 EIK 500
head( test2 )
# let num
# 1 ZUYW 153
# 2 PRNW 263
# 3 OTQS 355
# 4 NYRW 87
# 5 ZYST 365
# 6 TXRN 287
现在,我想将 test1 中的所有字符串组合(即 test1$let)与 test2 中的所有字符串组合粘贴,但前提是 test1$num 和 test2$num 的差值
一种方法是:
test.merg <- NULL
i <- 1; j <- 1
for(i in 1:dim(test1)[1] ) {
for( j in 1:dim(test2)[1] ) {
if( abs( test1[i,]$num - test2[j,]$num ) <= 100 ){
test.merg <- c(test.merg ,paste( test1[i,]$let , test2[j,]$let , sep="." ) )
}
j <- j+ 1
}
i <- i+ 1
}
head(test.merg)
#[1] "KDA.OTQS" "KDA.ZYST" "KDA.TVRX" "KDA.VYRQ" "KDA.XRQS" "KDA.WSUR"
这很好用,但我的实际数据集当然不同且巨大,而且需要很长时间才能完成。我确信必须有一种更有效的方法来做到这一点。尝试使用 apply 系列功能,但我能想到的唯一方法是:
test1.1 <- paste( test1$let , test1$num ,sep = "_")
test2.1 <- paste( test2$let , test2$num ,sep = "_")
test.merg.1 <- unlist(lapply( test1.1 , FUN = function(x) {lapply(
test2.1 , FUN = function(y) {
if( abs( as.numeric( str_split_fixed( x , "_" , 2 )[,2] ) - as.numeric( str_split_fixed( y , "_" , 2 )[,2]) ) <= 100){
paste( str_split_fixed(x , "_" , 2 )[,1] , str_split_fixed(y , "_" , 2 )[,1], sep = ".")
}
})
})
)
head(test.merg.1)
# [1] "KDA.OTQS" "KDA.ZYST" "KDA.TVRX" "KDA.VYRQ" "KDA.XRQS" "KDA.WSUR"
这已经将花费的时间减少了很多,几乎减少了 1/4,但是如果它可以变得更高效,那就太好了。更不用说,如果有一种完全不同且更好的方法来做到这一点,那就太棒了。
谢谢!
【问题讨论】:
-
或许
library(data.table); setDT(test2)[, num1 := num + 100];setDT(test1)[test2, on = .(num <= num1), allow.cartesian = TRUE][, , .(let, i.let)] -
你的实际数据集有多大?
-
@Moody_Mudskipper:数据来自基因序列,对于一个基因,将有超过 100,000 个基因片段组合粘贴到另外 100,000 个基因片段的所有组合中。
-
好吧,马上忘记我的解决方案:)。你在
abs(test1$num-test2$num) <= 100中的比例大约是多少?如果它非常低,我们可以考虑一个算法,但你的对象的大小是10.000.000.000*this proportion*size of an 8 character string,所以你可能需要另一种方法来解决你的一般问题...... -
一种解决方案可能是在
n块中切割两个向量,例如10,并应用这两个解决方案中的任何一个(它们是同一件事),因此您将扩展数据集根据我的建议,这将是n^2倍,100倍,因此您首先创建一个包含 1 亿行的表,根据您的条件对其进行过滤,保存过滤后的对象或将其保存在某处,然后继续下一个块组合
标签: r apply nested-loops