【问题标题】:Compare different columns in different data frames and create new loop R比较不同数据框中的不同列并创建新的循环 R
【发布时间】:2018-04-07 16:08:16
【问题描述】:

我有两个这样的数据框

a
   Id   start stop
1  ABC  25    30
2  ACD  40    60
3  BCD  55    60

b
   Id   start stop
1  XYZ  20    50
2  ZXY  80    90
3  YZX  50    70

并且我想合并两个数据帧中的 Id 并将它们放入一个新的(如下所示),如果第一个数据帧中起始列中的值较高并且停止列中的值较低第一个数据框。因此,由于 a 中的 [1,2] 高于 b 中的 [1,2] 并且 a 中的 [1,3] 低于 [1,3],因此两个数据帧中的 id 的 [1,1]进入新的数据框。

1  ABC  XYZ
2  BCD  YZX

我正在尝试使用 for 循环来执行此操作,如下所示,但似乎无法按我的意愿工作。任何帮助表示赞赏。我对 R 也很陌生,所以请保持简单:-)

a<-dataframe1
b<-dataframe2
for (i in 1:nrow(a)) {
  for (j in 1:nrow(b)) {
    if (a[i,2]>b[j,2] & a[i,3]<b[j,3]) {
      z<-as.data.frame(cbind(a[i,1],b[j,1]))
    }    
  }
}

【问题讨论】:

  • 你能更好地解释你的输出吗?现在很混乱。输出如何得到 ABC, XYZ ?
  • 同意@YOLO;输出的第一行不应该是ACD XYZ吗?
  • 是的,很抱歉,现在应该是正确的。

标签: r for-loop


【解决方案1】:

使用data.table 的解决方案可以实现为:

library(data.table)
setDT(a)
setDT(b)

a[b, .(Id_a = Id, Id_b = i.Id), on=.(start>=start , stop<=stop), nomatch = 0]
# Id_a Id_b
# 1:  ABC  XYZ
# 2:  BCD  YZX

选项#2:使用库sqldf

library(sqldf)
sqldf("SELECT a.ID as Id_a, b.ID as Id_b 
       FROM a, b
       WHERE a.start >= b.start AND a.stop <= b.stop")
#    Id_a Id_b
# 1  ABC  XYZ
# 2  BCD  YZX

数据

a <- read.table(text = 
"Id   start stop
ABC  25    30
ACD  40    60
BCD  55    60",
header = TRUE, stringsAsFactors = FALSE)

b <- read.table(text = 
"Id   start stop
XYZ  20    50
ZXY  80    90
YZX  50    70",
header = TRUE, stringsAsFactors = FALSE)

【讨论】:

    【解决方案2】:

    这是使用 R/Bioconductor 库 GenomicRanges 中的 findOverlaps 的一种可能性:

    library(GenomicRanges);
    gr.a <- makeGRangesFromDataFrame(cbind.data.frame(seqnames = 1, a), keep = T);
    gr.b <- makeGRangesFromDataFrame(cbind.data.frame(seqnames = 1, b), keep = T);
    
    hits <- findOverlaps(gr.a, gr.b, type = "within");
    cbind.data.frame(
        from_a = mcols(gr.a[queryHits(hits)])$Id,
        from_b = mcols(gr.b[subjectHits(hits)])$Id)
    #  from_a from_b
    #1    ABC    XYZ
    #2    BCD    YZX
    

    注意:我这里使用GenomicRanges,因为它的区间操作多种多样;似乎 R 库 intervals 提供了类似的功能。


    样本数据

    a <- read.table(text =
        "Id   start stop
    1  ABC  25    30
    2  ACD  40    60
    3  BCD  55    60", header = T, row.names = 1)
    
    b <- read.table(text =
       "Id   start stop
    1  XYZ  20    50
    2  ZXY  80    90
    3  YZX  50    70", header = T, row.names = 1)
    

    【讨论】:

      猜你喜欢
      • 2018-01-25
      • 2020-02-04
      • 2020-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多