我有两个数据框。第一个看起来像
dat <- data.frame(matrix(nrow=2,ncol=3))
names(dat) <- c("Locus", "Pos", "NVAR")
dat[1,] <- c("ACTC1-001_1", "chr15:35087734..35087734", "1" )
dat[2,] <- c("ACTC1-001_2 ", "chr15:35086890..35086919", "2")
其中chr15:35086890..35086919表示此范围内的所有数字。
第二个看起来像:
dat2 <- data.frame(matrix(nrow=2,ncol=3))
names(dat2) <- c("VAR","REF.ALT"," FUNC")
dat2[1,] <- c("chr1:116242719", "T/A", "intergenic" )
dat2[2,] <- c("chr1:116242855", "A/G", "intergenic")
我想通过dat $ Pos和dat2 $ VAR中的值合并它们。如果dat2 $ VAR中单元格中的单个数字包含在dat $ Pos中单元格的范围内,我想合并这些行。如果这发生多次(dat $ Pos中的多个范围内的dat2 $ VAR,我希望每次合并)。最简单的方法是什么?
答案 0 :(得分:1)
请尝试一下,让我们知道它是如何工作的。没有更大的数据集,有点难以拍摄。如果由于某种原因它不起作用,请从您的数据表中共享更多行(特别是那些匹配的行)
range.strings <- do.call(rbind, strsplit(dat$Pos, ":"))[, 2]
range.strings <- do.call(rbind, strsplit(range.strings, "\\.\\."))
mins <- as.numeric(range.strings[,1])
maxs <- as.numeric(range.strings[,2])
d2.vars <- as.numeric(do.call(rbind, str_split(dat2$VAR, ":"))[,2])
names(d2.vars) <- seq(d2.vars)
# row numebr is the row in dat
# col number is the row in dat2
matches <- sapply(d2.vars, function(v) mins < v & v <= maxs)
# create a column in dat to merge-by
dat <- cbind(dat, VAR=NA)
# use the VAR in dat2 as the merge id
sapply(seq(ncol(matches)), function(i)
dat$VAR <- dat2[i, "VAR"] )
merge(dat, dat2)
答案 1 :(得分:1)
这是一个解决方案,很短但不是特别有效,所以我不推荐它用于大数据。但是,您似乎表明您的数据不是那么大,请试一试并告诉我:
library(plyr)
exploded.dat <- adply(dat, 1, function(x){
parts <- strsplit(x$Pos, ":")[[1]]
chr <- parts[1]
range <- strsplit(parts[2], "..", fixed = TRUE)[[1]]
start <- range[1]
end <- range[2]
data.frame(VAR = paste(chr, seq(from = start, to = end), sep = ":"), x)
})
merge(dat2, exploded.dat, by = "VAR")
如果它太慢或者为你的需求使用太多内存,你将不得不实现更复杂的东西,而另一个问题看起来是一个很好的起点:Merge by Range in R - Applying Loops。