我有2个数据帧:
> access
V1 V2 V3
1 chr10 136122 136533
2 chr10 179432 179769
3 chr10 182988 183371
4 chr10 224234 224489
5 chr10 237693 237958
和
> peaks
V1 V2 V3
1 chr10 126122 126533
2 chr10 179450 179730
3 chr10 182788 183350
4 chr10 224244 224500
5 chr10 237695 237950
两个数据帧中的色域V2和V3是开始和结束区域(范围)。我希望将这些行保留在peaks
数据框中,access$V1 == peaks$V1
AND位于access
数据帧的范围(或区域)内。例如,新数据框将类似于:peaks
数据帧的
access
数据框中不存在第1行区域,因此会为其分配 U 类别。
peaks
的第二行属于access
数据框(第二行)的给定范围,并将分配类别 B 。
peaks
的第3行并未完全落入该区域,但它与access
第3行中的某个区域重叠,为此,我将指定类别 A
peaks
的第4行在访问的第4行中的区域结尾之后的第11行也没有完全重叠,这也将属于 A 类别
第5行属于该区域,因此属于 B 类别。
预期输出:
> newdf
V1 V2 V3 V4
1 chr10 126122 126533 U
2 chr10 179450 179730 B
3 chr10 182788 183350 A
4 chr10 224244 224500 A
5 chr10 237695 237950 B
以下是输入数据帧的输入:
> dput(peaks)
structure(list(V1 = structure(c(1L, 1L, 1L, 1L, 1L), .Label = "chr10", class = "factor"),
V2 = c(126122L, 179450L, 182788L, 224244L, 237695L), V3 = c(126533L,
179730L, 183350L, 224500L, 237950L)), .Names = c("V1", "V2",
"V3"), class = "data.frame", row.names = c(NA, -5L))
> dput(access)
structure(list(V1 = structure(c(1L, 1L, 1L, 1L, 1L), .Label = "chr10", class = "factor"),
V2 = c(136122L, 179432L, 182988L, 224234L, 237693L), V3 = c(136533L,
179769L, 183371L, 224489L, 237958L)), .Names = c("V1", "V2",
"V3"), class = "data.frame", row.names = c(NA, -5L))
修改
我的新访问权限df看起来像这样,现在我还想在我的最终输出df中附加最后一列:
> access
V1 V2 V3 V4
1 chr10 136122 136533 found
2 chr10 179432 179769 notFound
3 chr10 182988 183371 found
4 chr10 224234 224489 found
5 chr10 237693 237958 notFound
所以现在还有一个额外的条件,即如果访问中的行落在峰值范围内,那么还会在最后一个df的新列中附加V4中的值,如果找不到某个区域,则默认为{{1} }。因此,最终输出将是:
notFound
此处> newdf
V1 V2 V3 V4 V5
1 chr10 126122 126533 U notFound
2 chr10 179450 179730 B notFound
3 chr10 182788 183350 A found
4 chr10 224244 224500 A found
5 chr10 237695 237950 B notFound
中的值为notFound,因为未找到此区域,在其余情况下,我们从修改后的访问df中获取V5中的值。
答案 0 :(得分:1)
如果速度是一个问题,链接的data.table
解决方案可能会更好,但它也可以在dplyr
中实现,但可能要慢得多:
library(dplyr)
names(access)[2:3] <- c('start', 'end')
bind_cols(peaks[-1], access) %>%
rowwise() %>%
mutate(V4 = if_else(all(V2:V3 %in% start:end), 'B',
if_else(any(V2:V3 %in% start:end), 'A',
'U')))
结果:
Source: local data frame [5 x 6]
Groups: <by row>
# A tibble: 5 x 6
V2 V3 V1 start end V4
<int> <int> <fctr> <int> <int> <chr>
1 126122 126533 chr10 136122 136533 U
2 179450 179730 chr10 179432 179769 B
3 182788 183350 chr10 182988 183371 A
4 224244 224500 chr10 224234 224489 A
5 237695 237950 chr10 237693 237958 B
答案 1 :(得分:1)
尽管它还有很长的路要走。但它给出了预期的结果。
library(dplyr)
df<-cbind(peaks,access) #merging both df
colnames(df)<-c("pV1","pV2","pV3","aV1","aV2","aV3")
df<-df[c(which(df$pV1==df$aV1)),] # selecting rows with pV1=aV1
# creating U, A, B
U1<-df%>%
filter(pV2<aV2 & pV3<aV2)%>%
mutate(V4="U")
U2<-df%>%
filter(pV2>aV3 & pV3>aV3)%>%
mutate(V4="U")
B<-df%>%
filter(pV2>aV2 & pV3<aV3)%>%
mutate(V4="B")
A1<-df%>%
filter(pV2>aV2 & pV3>aV3)%>%
mutate(V4="A")
A2<-df%>%
filter(pV2<aV2 & pV3<aV3 & pV3>aV2)%>%
mutate(V4="A")
#merging U, A and B into newdf
newdf<-arrange(rbind(U1,U2,B,A1,A2),pV2)
newdf<-newdf[,-c(4:6)]
newdf
pV1 pV2 pV3 V4
1 chr10 126122 126533 U
2 chr10 179450 179730 B
3 chr10 182788 183350 A
4 chr10 224244 224500 A
5 chr10 237695 237950 B
答案 2 :(得分:1)
使用foverlaps功能可以使用以下语句完成:
setkey(setDT(access),V1,V2,V3)
setkey(setDT(peaks),V1,V2,V3)
access[,V4:= ifelse(!is.na(foverlaps(peaks, access, type="within", which=TRUE)$yid),"B",ifelse(!is.na( foverlaps(peaks, access, type="any", which=TRUE)$yid),"A","U"))]
它的运作方式如下:
答案 3 :(得分:0)
这是另一个(直接)解决方案,它使用最近实现的非equi连接,并在当前开发版本的data.table,v1.9.7中提供。请参阅安装说明here:
require(data.table) # v1.9.7+
setDT(access)
setDT(peaks)[, V4 := "U"] # no overlap
peaks[access, V4 := "A", on=.(V1, V2 <= V3, V3 >= V2)] # any overlap
peaks[access, V4 := "B", on=.(V1, V2 >= V2, V3 <= V3)] # completly within
# V1 V2 V3 V4
# 1: chr10 126122 126533 U
# 2: chr10 179450 179730 B
# 3: chr10 182788 183350 A
# 4: chr10 224244 224500 A
# 5: chr10 237695 237950 B
向peaks
添加一个新列,全部是&#34; U&#34;。然后替换那些与&#34; A&#34;有任何重叠的行。这将包含所有在&#34; 内完全&#34;的行。然后再次执行条件连接,但这次只是完全在内,并用&#34; B&#34;替换。
请注意,foverlaps()
解决方案也可以正常工作(它也来自data.table包)。但是新的非equi连接符合[.data.table
语法,允许在加入时聚合/添加/更新cols 。