这个问题与Efficiently merging two data frames on a non-trivial criteria和Checking if date is between two dates in r有些关系,我在这里发布的问题是询问是否存在该特性:GitHub issue
我希望使用dplyr::left_join()
连接两个 Dataframe 。我用于连接的条件是小于、大于,即<=
和>
。dplyr::left_join()
是否支持此功能?或者键之间是否仅使用=
运算符。这可以直接从SQL运行(假设 Dataframe 在数据库中)
以下是MWE:我有两个数据集,一个是公司年(fdata
),另一个是每5年发生一次的调查数据,所以对于fdata
中两个调查年之间的所有年份,我加入了相应的调查年数据。
id <- c(1,1,1,1,
2,2,2,2,2,2,
3,3,3,3,3,3,
5,5,5,5,
8,8,8,8,
13,13,13)
fyear <- c(1998,1999,2000,2001,1998,1999,2000,2001,2002,2003,
1998,1999,2000,2001,2002,2003,1998,1999,2000,2001,
1998,1999,2000,2001,1998,1999,2000)
byear <- c(1990,1995,2000,2005)
eyear <- c(1995,2000,2005,2010)
val <- c(3,1,5,6)
sdata <- tbl_df(data.frame(byear, eyear, val))
fdata <- tbl_df(data.frame(id, fyear))
test1 <- left_join(fdata, sdata, by = c("fyear" >= "byear","fyear" < "eyear"))
我得到
Error: cannot join on columns 'TRUE' x 'TRUE': index out of bounds
除非left_join
可以处理这个条件,但是我的语法缺少了什么?
5条答案
按热度按时间8dtrkrch1#
data.table
从v1.9.8开始添加非对等连接您还可以在1.9.6中使用
foverlaps
,只需多花点功夫。50few1ms2#
使用
filter
。(但是注意,这个答案 * 没有 * 产生正确的LEFT JOIN
;但MWE使用INNER JOIN
给出了正确的结果。)dplyr
包不喜欢合并两个表,因为没有合并的内容,所以在下面的代码中,我在两个表中创建了一个伪变量,然后过滤,最后删除dummy
:请注意,如果您在PostgreSQL中执行此操作(例如),查询优化器会看穿
dummy
变量,如以下两个查询解释所示:而用SQL做得更干净,会得到 * 完全 * 相同的结果:
avwztpqn3#
这看起来就像是包fuzzyjoin要处理的任务,包中的各种函数看起来和工作起来都类似于dplyrjoin函数。
在这种情况下,
fuzzy_*_join
函数中的一个将为您工作。dplyr::left_join
和fuzzyjoin::fuzzy_left_join
之间的主要区别在于,您使用match.fun
参数给予了匹配过程中要使用的函数列表。注意,by
参数的编写方式仍然与left_join
中的相同。下面是一个例子,我用来匹配的函数是
>=
和<
,分别用于fyear
到byear
的比较和fyear
到eyear
的比较。xqkwcwgp4#
dplyr
的dev版本现在包含了执行非相等连接的能力,语法几乎和您尝试的完全一样。对于具有许多部分匹配的数据,这将比在过度包含连接之后使用fuzzyjoin
或filter
步骤更高效。fkvaft9z5#
一种选择是将行连接为列表列,然后取消嵌套该列: