在管道运营商中传递价值

时间:2016-12-06 12:13:25

标签: r dplyr pipeline

我在R中工作,有两个表由id变量连接(出于某些原因,我不想合并它们)。示例性对象如下所示:

a <- data.frame(id=c(1L,2L,3L),
            var1=c(0,1,3))
b <- data.frame(id=c(1L,1L,2L,2L,3L,3L),
            var2=rnorm(6))

我想要做的是在第一个数据库中查找关于var1上给定条件的行,仅选择Ids然后使用这些id值来过滤数据库2中的观察。我想知道我是否可以在一个管道中执行此操作,如如下:

a %>% 
filter(var1==1) %>% 
select(id) %>%
filter(b,id==.)

a %>% 
filter(var1==1) %>% 
select(id) %>% c() %>% unlist()
filter(b,id==.)

两个示例都不起作用,可能是因为我只能通过管道运算符而不是原子值传递data.frames或其他对象。我是对的吗?

6 个答案:

答案 0 :(得分:2)

好像您正在寻找semi_join

a %>% filter(var1 == 1) %>% semi_join(b, ., by = "id")
#  id       var2
# 1  2  0.8283845
# 2  2 -0.5286006
  

<强> semi_join

     

返回x中匹配值的所有行,y   只保留x中的列。

     

半连接与内连接不同,因为内连接将是   为y的每个匹配行返回一行x,其中半连接将为   永远不要复制x行。

答案 1 :(得分:1)

其他答案为如何获得所需结果提供了很好的解决方案。要回答问题末尾的问题:

您的示例不会失败,因为管道在某种程度上限制了它的管道。问题在于管道运算符%>%实际上做了什么。它将左侧的结果作为右侧的FIRST参数进行管道,无论您在何处使用.。因此,filter(b,id==.)它不会过滤b,它实际上会过滤您之前语句的结果。在第一个示例中调用traceback()时,您可以看到此信息。如果我们看一下两个相关的结果:

....
9: filter(., b, id == .)
....
1: a %>% filter(var1 == 1) %>% select(id) %>% filter(b, id == .)

1:我们会看到您的代码,但在9:,我们会看到R实际读取的内容。filter(b, id == .)实际上被视为filter(., b, id == .)

答案 2 :(得分:0)

我只是将它分为两​​个阶段:

selected_ids = a %>% filter(var1 == 1) %>% select(id) %>% unlist()
b %>% filter(id %in% selected_ids)
#   id       var2
# 1  2  0.8054040
# 2  2 -0.5000918

或合并数据集并直接执行操作:

merged_data = merge(a, b)
merged_data %>% filter(var1 == 1)
#   id var1       var2
# 1  2    1  0.8054040
# 2  2    1 -0.5000918

我更喜欢第二种选择。

答案 3 :(得分:0)

我们可以从id a获取var = 1并选择b匹配的id中的所有行

b[b$id %in% a$id[a$var1 == 1], ]

#  id   var2
#3  2 1.0294
#4  2 0.7369

类似的事情可以在dplyr中通过

完成
library(dplyr)
b %>%
filter(id == a$id[a$var1 == 1])

答案 4 :(得分:0)

以下是使用data.table

的选项
setDT(a)[b, on = "id"][var1==1]

或使用dplyr

left_join(b, a, by = "id") %>% 
                     filter(var1==1)

答案 5 :(得分:0)

你可以做到这一点(虽然我同意其他人的意见,我更喜欢合并或某种联合)。

您可以通过在表达式(.)周围添加括号来解决包含{}作为第一个参数的问题。然后,将.视为data.frame(即使在select之后),并调用所需的列。像这样:

a %>% 
  filter(var1==1) %>% 
  {filter(b,id==.$id)}

返回:

  id       var2
1  2 -0.2992151
2  2 -0.4115108