3

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

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 中的单元格范围内,我想合并这些行。如果这种情况不止一次发生(dat2$VAR 在 dat$Pos 的多个范围内,我希望它每次都合并)。最简单的方法是什么?

4

2 回答 2

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)
于 2012-12-04T01:03:31.383 回答
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

于 2012-12-04T01:53:41.720 回答