所以情况是这样的: 我基本上有一个数据框,其中包含大约100,000行数据。我对特定的数据列POS感兴趣,我想检查POS的值是否在另一个数据框的两个值之间,即开始和结束,并跟踪那些数据的实例数。
例如,在我的第一个数据框中,我有类似
的内容.componentHolder {
width: 100px;
height: 120px;
border: 1px solid black;
padding: 0px;
margin: 0px;
float: left; // I used float instead of inline-block
}
在我的其他数据框中,我有像
这样的东西ID POS
A 20
B 533
C 600
我想知道POS中有多少项在START-END范围内。所以在这种情况下,有两个项目。另外,如果可能的话,我也可以在开始和结束之间获得POS的ID吗?
如何在不使用嵌套for循环的情况下进行此操作?
答案 0 :(得分:6)
这是一个在数据库环境中可能发生的相当常见的问题。以下是使用sqldf
的解决方案:
library(sqldf)
query <- "SELECT POS, ID FROM df1 INNER JOIN df2 "
query <- paste0(query, "ON df1.POS BETWEEN df2.START AND df2.END")
sqldf(query)
如果第二个数据框中的范围可能重叠,则上述查询可能会返回给定POS
值的多个结果。在这种情况下,请将SELECT POS
替换为SELECT DISTINCT POS
。
答案 1 :(得分:6)
我们可以使用data.table
library(data.table)
setDT(df1)[df2, on = .(POS > START, POS <= END)][, sum(!is.na(ID))]
#[1] 2
答案 2 :(得分:1)
我们可以使用mapply
中的base-R
作为:
df1[mapply(function(x)any(x >= df2$START & x <= df2$END),df1$POS),]
# ID POS
#2 B 533
#3 C 600
数据强>
df1 <- read.table(text =
"ID POS
A 20
B 533
C 600", header = T)
df2 <- read.table(text =
"START END
123 150
489 552
590 600", header = TRUE)
答案 3 :(得分:1)
数据框:main
ID POS
A 20
B 533
C 600
数据框:ran
START END
123 150
489 552
590 600
简单的sapply
应该足以满足您的使用案例:
sapply(main$POS, function(x) { sum(x>=ran$START & x<=ran$END) })
将返回:
[1] 0 1 1
您可以将其绑定回main
数据框中的新列:
main$Count <- sapply(main$POS, function(x) { sum(x>=ran$START & x<=ran$END) }))
ID POS count
1 A 20 0
2 B 533 1
3 C 600 1
这也适用于重叠范围。