-5

私は次のデータを持っています:

df1 <- data.frame(chrom=c("chr1","chr2","chr5"),
    start=c(10,20,30), end=c(100,200,300), stringsAsFactors=FALSE)

df2 <- data.frame(chrom=c("chr1","chr4","chr2","chr1"),
    start=c(15,500,150,200), end=c(75,1000,300,300), stringsAsFactors=FALSE)

私は次のことをしたい:

for(i in 1:nrow(df2)) {
    # only if this condition is true (i.e. if there is overlap)
    if((df1$start <= df2$start && df1$end >= df2$start) ||
       (df1$start >= df2$start && df1$start <= df2$end)) {
        x <- df2[which(df2$chrom %in% df1$chrom),]
    }
}

答えは次のようになります。

df3 <- data.frame(chrom=c("chr1", "chr2"), start=c(15,150),
    end=c(75,300), stringsAsFactors=FALSE)

ご迷惑をおかけして申し訳ありません。

人々は私の質問に非常に辛抱強く、それは非常に有益で学習的な経験でした。ただし、ループがどのように機能するかを理解しようとしています。ループについて考えれば考えるほど、混乱が生じます。例えば:

for(i in 1:nrow(df2)) {
    x <- df2[which(df2$chrom %in% df1$chrom),]
}

まったく同じことをします:

x <- df2[which(df2$chrom %in% df1$chrom),]

したがって、ループも必要ありません。これはどのように可能ですか?私whichはあなたのためにループをしていると思いますか?

4

1 に答える 1

2

さらに先に進むことができます:

df2[df2$chrom %in% df1$chrom,]

Rは「ベクトル化」されているため、指定した条件に一致するdf2からの行を返します。それを2つの部分に分けます:

> df2$chrom %in% df1$chrom  
[1] TRUE FALSE  TRUE  TRUE

これは、行1、3、および4がこの条件を満たすことを意味します。df2次に、そのブールベクトルを使用してサブセット化します。Rは、指定した行のみを返しますTRUE

> df2[c(TRUE, FALSE, TRUE, TRUE),]
  chrom start end
1  chr1    15  75
3  chr2   150 300
4  chr1   200 300
> 

これは役に立ちますか?

コメントごとに編集:

非常に非Rな方法はforループにネストされます...

output <- data.frame()
for(i in 1:nrow(df2)) {
  foo <- NULL
  for(j in 1:nrow(df1)) {
    if(df1$chrom[j]==df2$chrom[i]) {
      foo <- df2[i,]
    }
  }
  output <- rbind(output, foo)
}

しかし、これはまさにRでしてはいけないことです...

于 2012-04-10T19:25:08.380 に答える