基于R中的不相同值合并数据帧

时间:2012-12-04 00:34:05

标签: r merge

我有两个数据框。第一个看起来像

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,我希望每次合并)。最简单的方法是什么?

2 个答案:

答案 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)

MERGE

# 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