我有以下数据:
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
正在为你做循环?
答案 0 :(得分:2)
你可以走得更远:
df2[df2$chrom %in% df1$chrom,]
由于R是“矢量化”,因此您将从df2返回与您给定的条件匹配的行。将其分为两部分:
> 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 ...中无法做到的事情。