我有一个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中执行此操作?
答案 0 :(得分:2)
这是使用data.table
的另一种可能的解决方案。首先我们将数据melt
改为长格式,根据前Set
列名称添加df
列,然后将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
答案 1 :(得分: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
(但行名不重要。)
理想情况下,您会生成类似的数据,但如果您已经按照自己提供的格式生成数据,则可以通过它进行转换(假设您的第一个数据的名称是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
只匹配一次。)