所以我在R上工作,有一个大的数据,包含一个载体,它有像这样的基因组位置:
2655180
2657176
2658869
第二个数据帧具有一系列的位置和类似的基因:
chr1 100088228 100162167 AGL
chr1 107599438 107600565 PRMT6
chr1 115215635 115238091 AMPD1
chr1 11850637 11863073 MTHFR
chr1 119958143 119965343 HSD3B2
chr1 144124628 144128902 HFE2
chr1 150769175 150779181 CTSK
chr1 154245300 154248277 HAX1
chr1 155204686 155210803 GBA
chr1 156084810 156108997 LMNA
其中第二列和第三列分别是基因的开始和结束。我要做的是检查第一数据帧中的一行是否符合第二数据帧的范围,如果符合,则将基因(第二数据帧的第4列)添加到第一数据帧中。
我的当前实现使用嵌套的for循环来检查第一个dataframe中的每个条目和第二个dataframe中的所有条目。有什么R函数可以帮助我完成这个任务吗?
简单地说,我需要检查第一个向量中一行中的值是否在大小不同的第二个向量中指定的范围内,然后从第二个向量中提取一个值。
发布于 2014-07-15 11:57:46
使用dplyr
getValue <- function(x, data) {
tmp <- data %>%
filter(V2 <= x, x <= V3)
return(tmp$V4)
}
x <- c(107599440, 150769180, 155204690)
sapply(x, getValue, data=df)
返回:
[1] "PRMT6" "CTSK" "GBA"
注意:我将您的数据复制到一个dataframe df
中,其中包含列名V1
、V2
、V3
和V4
。列V2
和V3
是范围的上下值。
df <- read.table(text="chr1 100088228 100162167 AGL
chr1 107599438 107600565 PRMT6
chr1 115215635 115238091 AMPD1
chr1 11850637 11863073 MTHFR
chr1 119958143 119965343 HSD3B2
chr1 144124628 144128902 HFE2
chr1 150769175 150779181 CTSK
chr1 154245300 154248277 HAX1
chr1 155204686 155210803 GBA
chr1 156084810 156108997 LMNA", stringsAsFactors=FALSE)
更新:
如果有多个匹配,这将返回第一个匹配:
getValue <- function(x, data) {
tmp <- data %>%
filter(V2 <= x, x <= V3) %>%
filter(row_number() == 1)
return(tmp$V4)
}
有多个排序函数。有关更多信息,请访问?row_number
。
发布于 2014-07-15 11:42:31
这就是你要的。这一答案取决于评论中讨论的假设,即范围既不重叠,也不相互对接。
d <- read.table(text='chr1 100088228 100162167 AGL
chr1 107599438 107600565 PRMT6
chr1 115215635 115238091 AMPD1
chr1 11850637 11863073 MTHFR
chr1 119958143 119965343 HSD3B2
chr1 144124628 144128902 HFE2
chr1 150769175 150779181 CTSK
chr1 154245300 154248277 HAX1
chr1 155204686 155210803 GBA
chr1 156084810 156108997 LMNA')
# Since your original vector does not contain positions
# that are in any of the ranges in your second data.frame,
# I choose new values and commented the range they should belong to.
v <- read.table(text="
119958153 # HSD3B2
154245310 # HAX1
156084820 # LMNA")
# order the first data.frame by the ranges
d <- d[order(d[[2]]), ]
# create a vector breaks from the interval ranges
breaks <- as.vector(do.call(rbind, d[c(2,3)]))
ints <- ceiling(findInterval(v[[1]], breaks)/2)
v$AGL <- d[ints, 4]
# V1 AGL
# 1 119958153 HSD3B2
# 2 154245310 HAX1
# 3 156084820 LMNA
发布于 2014-07-15 11:52:19
我知道您要求一个函数,但是这里有一种方法不需要嵌套循环,使用一些假数据。
x <- as.vector(c(1:3,6:9)) #Create a vector with values 1 to 3, and 6 to 9
y <- c(1:5) #Create a vector with values 1 to 5
inrange <- matrix(nrow=6,ncol=1) #Create an empty matrix the same length as x
for (i in 1:nrow(x)){
inrange[i] <- ifelse((x[i] <= max(y) & x[i] >= min(y)),
1,0) #This if statement evaluates each row of x to determine
} #whether the row is greater than/equal to the miniumum
#or less than/equal to the maximum of y
如果x的值在y的范围内,则"inrange“的值现在为1,如果没有,则为0。
https://stackoverflow.com/questions/24766104
复制相似问题