R 通过另一个数据帧的两列中的值来子集两个数据帧中的数据帧

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的方式实现这一点,但我非常确定我

我有两个数据帧。 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的方式实现这一点,但我非常确定我可以以某种方式使用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)

df1
base 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中.