R 通过另一个数据帧的两列中的值来子集两个数据帧中的数据帧
我有两个数据帧。 df1看起来像(或我感兴趣的df1列): df2看起来像:R 通过另一个数据帧的两列中的值来子集两个数据帧中的数据帧,r,dplyr,R,Dplyr,我有两个数据帧。 df1看起来像(或我感兴趣的df1列): df2看起来像: start end 2 17 24 29 我想保持df1中的位置仅在(=)df2的开始和结束坐标之间,以便df1在过滤后看起来像这样: position 2 6 12 25 然后我想在另一个数据帧中保留过滤掉的df1的“剩余”值,我们称之为df4 df4看起来像: position 18 31 我可以使用for循环(来自perl,目前正在学习R)以perl的方式实现这一点,但我非常确定我
start end
2 17
24 29
我想保持df1中的位置仅在(=)df2的开始和结束坐标之间,以便df1在过滤后看起来像这样:
position
2
6
12
25
然后我想在另一个数据帧中保留过滤掉的df1的“剩余”值,我们称之为df4
df4看起来像:
position
18
31
我可以使用for循环(来自perl,目前正在学习R)以perl的方式实现这一点,但我非常确定我可以以某种方式使用filter或其他dplyr或base R组合函数来实现这一点
任何帮助都将不胜感激
编辑:添加了df4计算,因为我的问题被标记为重复,这在其他类似的线程中找不到。这是我有兴趣做的事情,使我的代码更快 我们可以
full_join
这两个数据帧,然后过滤start
和end
列中的行。示例中的标志
列仅用于连接。最后,我们可以使用distinct
删除重复的行
library(dplyr)
df3 <- df1 %>%
mutate(Flag = 1) %>%
full_join(df2 %>% mutate(Flag = 1), by = "Flag") %>%
filter(position >= start, position <= end) %>%
distinct(position)
df3
# position
# 1 3
# 2 6
# 3 12
# 4 25
库(dplyr)
df3%
变异(标志=1)%>%
完全联接(df2%>%变异(Flag=1),by=“Flag”)%>%
过滤器(位置>=开始,位置%
不同(位置)
df3
#位置
# 1 3
# 2 6
# 3 12
# 4 25
数据
df1 <- read.table(text = "position
3
6
12
18
25
31", header = TRUE)
df2 <- read.table(text = "start end
2 17
24 29",
header = TRUE)
df1我们可以full_join
这两个数据帧,然后过滤start
和end
列中的行。示例中的标志
列仅用于连接。最后,我们可以使用distinct
删除重复的行
library(dplyr)
df3 <- df1 %>%
mutate(Flag = 1) %>%
full_join(df2 %>% mutate(Flag = 1), by = "Flag") %>%
filter(position >= start, position <= end) %>%
distinct(position)
df3
# position
# 1 3
# 2 6
# 3 12
# 4 25
库(dplyr)
df3%
变异(标志=1)%>%
完全联接(df2%>%变异(Flag=1),by=“Flag”)%>%
过滤器(位置>=开始,位置%
不同(位置)
df3
#位置
# 1 3
# 2 6
# 3 12
# 4 25
数据
df1 <- read.table(text = "position
3
6
12
18
25
31", header = TRUE)
df2 <- read.table(text = "start end
2 17
24 29",
header = TRUE)
df1base R
解决方案(无需软件包)
请注意:
- 这基本上是一个双循环,我不知道如何用
base::
解决这个问题
- 是否应该包含边界值?您对“介于之间”的定义非常模糊。目前,我没有包含边界值。您可以使用
=
更改边界值
要获得“剩余”,请使用否定:
df1[!keepRows,, drop = FALSE]
base R
解决方案(无需软件包)
请注意:
- 这基本上是一个双循环,我不知道如何用
base::
解决这个问题
- 是否应该包含边界值?您对“介于之间”的定义非常模糊。目前,我没有包含边界值。您可以使用
=
更改边界值
要获得“剩余”,请使用否定:
df1[!keepRows,, drop = FALSE]
这里有一个base R
选项
do.call(rbind, Map(function(i, j)
df1[df1$position > i & df1$position < j, , drop = FALSE],
df2$start, df2$end))
# position
#1 3
#2 6
#3 12
#5 25
或者使用来自数据表的非等联接
setDT(df2)[df1, on = .(start < position, end > position), .(position), nomatch = 0]
# position
#1: 3
#2: 6
#3: 12
#4: 25
setDT(df2)[df1,on=(开始<位置,结束>位置),(位置),nomatch=0]
#位置
#1: 3
#2: 6
#3: 12
#4: 25
数据
df1这里有一个base R
选项
do.call(rbind, Map(function(i, j)
df1[df1$position > i & df1$position < j, , drop = FALSE],
df2$start, df2$end))
# position
#1 3
#2 6
#3 12
#5 25
或者使用来自数据表的非等联接
setDT(df2)[df1, on = .(start < position, end > position), .(position), nomatch = 0]
# position
#1: 3
#2: 6
#3: 12
#4: 25
setDT(df2)[df1,on=(开始<位置,结束>位置),(位置),nomatch=0]
#位置
#1: 3
#2: 6
#3: 12
#4: 25
数据
df1单线简单基本解决方案:
df1[df1$position %in% unlist(apply(df2,1,function(x) x["start"]:x["end"])),]
应用程序只生成介于开始和结束之间的所有情况的向量。单行简单基本解决方案:
df1[df1$position %in% unlist(apply(df2,1,function(x) x["start"]:x["end"])),]
apply只生成介于开始和结束之间的所有案例的向量。这里是另一个从df2开始的例子(我不认为这比Andre的方法更明智):
在做出决定之前,您可能应该对建议的方法运行一些基准测试。这里是另一个从df2开始的步骤(我不认为这比Andre的方法更明智):
在做出决定之前,您可能应该对建议的方法运行一些基准测试。Hello www,这对我来说是一个易于理解的dplyr解决方案!我对dplyr比base r更为熟悉,因此比X更适合于伟大的响应!而且,这个答案按照我的要求提供了一个数据帧!有没有办法保持在df4中过滤掉的内容无需重复此代码?(参见问题编辑)我发现了,我想。我可以使用:df4Hello www,这对我来说是一个易于理解的dplyr解决方案!我对dplyr比base r更熟悉,所以比X更适合于伟大的响应!而且,这个答案按照我的要求提供了一个数据帧!有没有一种方法可以保持在df4中过滤掉的内容而不必重复此代码?(见问题编辑)我发现了,我想。我可以使用:DF4根据你的建议把我的问题说得更清楚。根据你的建议把我的问题说得更清楚。你是说DF4是18,31,纠正了这个!你是说DF4是18,31,纠正了这个!快速检查后,这似乎是最快的解决方案。快速检查后,这似乎是最快的解决方案@AndreElrico类似DT的东西有时必须转换数据。这并不是所有问题的理想解决方案。不过,如果数据已经是data.table,那也没关系。@AndreElrico因为我没有使用data.table
我使用的函数实际上是来自dplyr
。不过谢谢你的提示。我忘了它不在base中。@AndreElrico类似DT的东西有时必须转换数据。这并不是所有问题的理想解决方案。但是,如果数据已经是data.table,这也没关系。@AndreElrico因为我没有使用数据。table
我使用的函数实际上是来自dplyr
。不过谢谢你的提示。我忘了它不在base中.