[英]How to find the number of cells in a column that match another data frame's range?
我有一個data.frame1像:
Input_SNP_CHR Input_SNP_BP Set_1_CHR Set_1_BP Set_2_CHR Set_2_BP Set_3_CHR Set_3_BP
chr4 184648954 chr18 63760782 chr7 135798891 chr7 91206783
chr13 45801432 chr14 52254555 chr1 223293324 chr4 184648954
chr18 71883393 chr22 50428069 chr7 138698825 chr18 63760782
我有另一個data.frame2像:
CHR BP1 BP2 Score Value
chr1 29123222 29454711 -5.7648 599
chr13 45799118 45986770 -4.8403 473
chr5 46327104 46490961 -5.3036 536
chr6 50780759 51008404 -4.4165 415
chr18 63634657 63864734 -4.8096 469
chr1 77825305 78062178 -5.4671 559
我想知道data.frame1中每對中有多少行(一對是Input_SNP_CHR和Input_SNP_BP)兩者匹配CHR並且落在data.frame2的BP1和BP2之間。 例如,在我的第一對(Input_SNP對)中,我有一個匹配。 這是第二行,其中Input_SNP的CHR(chr13)和BP(45801432)在data.frame2中與CHR(chr13)和BP范圍(在45799118和45986770之間)的行匹配。 對於我的第二對(Set_1對),我還有1個匹配(chr18),BP 63760782與chr18的第5行data.frame2和BP范圍匹配。
我想要的輸出是:
Input_SNP Set_1 Set_2 Set_3
1 1 0 1
我怎么會在R中這樣做呢?
這是使用data.table
的另一種可能的解決方案。 首先,我們將數據melt
為長格式,根據第一個df
列名添加Set
列,然后運行foverlaps
與table
結合以檢查頻率
library(data.table) # v 1.9.6+
Ldf <- melt(setDT(df), measure = patterns("CHR", "BP")) # Create a column for BP and CHR
Names <- unique(sub("(.*_.*)_.*", "\\1", names(df))) # Creates a sets names indx
setnames(Ldf[, variable := factor(Names[variable])], c("Set", "CHR", "BP1")) # Rename
Ldf[, BP2 := BP1] # Creating right boundary for foverlaps
setkeyv(Ldf, names(Ldf)[-1]) # Keying for foverlaps
table(foverlaps(setDT(df2), Ldf, nomatch = 0L)$Set) # Running fovelaps and checking freqs
# Input_SNP Set_1 Set_2 Set_3
# 1 1 0 1
我認為你的第一個data.frame中的數據應該像這樣格式化
# CHR type BP
# 1.1 chr4 Input_SNP 184648954
# 1.2 chr13 Input_SNP 45801432
# 1.3 chr18 Input_SNP 71883393
# 2.1 chr18 Set_1 63760782
# 2.2 chr14 Set_1 52254555
# 2.3 chr22 Set_1 50428069
# 3.1 chr7 Set_2 135798891
# 3.2 chr1 Set_2 223293324
# 3.3 chr7 Set_2 138698825
# 4.1 chr7 Set_3 91206783
# 4.2 chr4 Set_3 184648954
# 4.3 chr18 Set_3 63760782
(但行名不重要。)
理想情況下,你會生成這樣的數據,但如果你已經按照你提供的格式生成它,你可以通過它來轉換它(假設你的第一個data.frame的名字是df
)
type_list=lapply(strsplit(colnames(df),"_"),
function(x) c(paste0(x[1],"_",x[2])))
df_new=do.call("rbind",
lapply(split(1:ncol(df),sort(rep(1:(ncol(df)/2),times=2))),
function(idxs) {
data.frame(CHR=df[,idxs[1]],
type=type_list[[idxs[1]]],
BP=df[,idxs[2]])}))
然后它只是兩行基礎R來完成你的任務(假設第二個data.frame是df2
)
df_new_2=within(merge(df_new,df2,by="CHR"),
cnt<-BP>=BP1&BP<=BP2)
sapply(split(df_new_2,df_new_2$type),function(x) sum(x$cnt))
#Input_SNP Set_1 Set_2 Set_3
# 1 1 0 1
(我只有一次擊中Set_3
因為只有chr18
匹配。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.