如果我运行以下简单示例,我会得到预期的输出:
library(dplyr)
library(dtplyr)
library(data.table)
dt1 <- lazy_dt(data.table(a = 1:5, b = 6:10))
dt2 <- lazy_dt(data.table(a = letters[1:5], b = 6:10))
dt1 %>%
left_join(
dt2,
by = "b"
) %>%
as.data.table()
> b a.x a.y
> 1: 6 1 a
> 2: 7 2 b
> 3: 8 3 c
> 4: 9 4 d
> 5: 10 5 e
请注意,使用添加和后缀a
的标准dplyr
格式正确管理冲突的列。.x
.y
但是,如果我现在尝试删除其中一列:
dt1 %>%
left_join(
dt2,
by = "b"
) %>%
select(
-a.y
) %>%
as.data.table()
> Error in is_character(x) : object 'a.y' not found
有趣的是,如果我尝试选择其中一a
列 ( select(a.x)
),我会得到相同的错误,但是...select(a)
dt1 %>%
left_join(
dt2,
by = "b"
) %>%
select(
a
) %>%
as.data.table()
> a.b
> 1: 1
> 2: 2
> 3: 3
> 4: 4
> 5: 5
其中选定的列是明确的dt1$a
,但由于某种原因,给定的列名是a.b
。(如果我尝试select(a.b)
,我会得到同样的object not found
错误)。
同时,如果我尝试 drop a
,两a
列都会被删除:
dt1 %>%
left_join(
dt2,
by = "b"
) %>%
select(
-a
) %>%
as.data.table()
> b
> 1: 6
> 2: 7
> 3: 8
> 4: 9
> 5: 10
那么,如何select
在表具有冲突(而不是连接)列的连接中使用?
编辑:
正如一些答案中提到的,我显然可以在选择之前执行惰性评估,这很有效。但是,它会引发警告(因为我想将我的对象保留为 a data.table
,而不是 a data.frame
)所以它似乎不是预期的方法:
dt1 %>%
left_join(
dt2,
by = "b"
) %>%
as.data.table() %>%
select(
-a.x
)
> b a.y
> 1: 6 a
> 2: 7 b
> 3: 8 c
> 4: 9 d
> 5: 10 e
> Warning message:
> You are using a dplyr method on a raw data.table, which will call the data
> frame implementation, and is likely to be inefficient.
> *
> * To suppress this message, either generate a data.table translation with
> * `lazy_dt()` or convert to a data frame or tibble with
> * `as.data.frame()`/`as_tibble()`.