我有两个数据帧(df1
和df2
),结果为guest_id
,money
和date
我想通过使用这些来确定第一个数据帧中的元素是否也在第二个数据帧中。为此,我希望使用我将在df1
中添加的变量,并且我将命名为{{ 1}},如果match
中的元素也在df1
中,则取1,否则为0
但是它们不完全匹配(因为报告中有一些错误),所以我不能简单地将它们合并为这3列或类似的东西
因此,我想知道:
进行一些简单的比较df2
的{{1}}与guest_id
的{{1}}匹配1>
df1
和guest_id
时,我想检查df2
和df1
。我想这样做:
df2
money
,对于给定date
的{{1}} money
与money
中可能出现的所有df1
之间的差异(但仅限于给定的guest_id
)。如果发生的事件接近0(在-1和1之间,或money
1,如果我使用df2
),那么我认为guest_id
匹配<=
:我做的事情与abs()
相同;我认为如果money
中的date
介于money
之间; date
,然后df1
匹配(再次,我想仅针对给定的df2$date - 5
进行这些比较,而不查看整个数据帧,否则它可能与df2$date + 5
或date
,但对于另一位客人,这就是我遇到的问题)guest_id
,money
和date
,我可以在我的guest_id
变量中加1,否则它是0 < / LI>
我使用money
,但由于我是初学者,因此无法找到正确使用的函数序列。我也宁愿避免使用date
,因为我正在处理大型数据帧,因此获取结果肯定会花费太多时间
总结一下,这就是我所拥有的:
match
结果:
dplyr
有没有人知道如何做到这一点(甚至是这个问题的完全不同的方法)?
答案 0 :(得分:1)
我建议先进行左连接,然后应用条件并查找df1中的任何原始行是否匹配:
library('stringr')
library('dplyr')
df3 <- left_join(df1, df2, by = 'guest_id') %>%
mutate_at(vars(contains('date')), ymd) %>%
# Checking for your condition
mutate(match = (abs(money.x - money.y) < 1) & (abs(date.x - date.y) < 5)) %>%
# Cleaning data.frame a bit
select(-money.y, -date.y) %>%
setNames(str_replace(names(.), '\\.x', '')) %>%
# Finding if rows had a match
group_by(guest_id, money, date) %>%
summarise(match = any(match, na.rm = TRUE))
df3
# A tibble: 6 x 4 # Groups: guest_id, money [?] guest_id money date match <int> <dbl> <date> <lgl> 1 1 10.2 2017-01-01 TRUE 2 1 10.3 2000-01-01 FALSE 3 1 50.0 2017-01-01 FALSE 4 2 9.5 2017-01-01 TRUE 5 2 10.5 2017-01-01 TRUE 6 3 100.0 2000-01-01 FALSE
data.frame
我曾用于测试:
df1 <- structure(list(guest_id = c(1L, 1L, 1L, 2L, 2L, 3L), money = c(10.2,
10.3, 50, 10.5, 9.5, 100), date = c("2017-01-01", "2000-01-01",
"2017-01-01", "2017-01-01", "2017-01-01", "2000-01-01")), .Names = c("guest_id",
"money", "date"), class = "data.frame", row.names = c(NA, -6L
))
df2 <- structure(list(guest_id = c(1L, 1L, 2L), money = c(10L, 10L,
10L), date = c("2017-01-01", "2015-01-01", "2017-01-03")), .Names = c("guest_id",
"money", "date"), class = "data.frame", row.names = c(NA, -3L
))
答案 1 :(得分:1)
最近版本的data.table
支持非equi 加入非常方便和有效,特别是与加入上的更新和{{{ 1}}:
.EACHI
library(data.table) # CRAN version 1.10.4 used # tolerances tol_m <- 1 tol_d <- 5 data.table(df1)[ # join with modified df2 data.table(df2)[ # create helper columns for non-equi joins , `:=`(m1 = money - tol_m, m2 = money + tol_m, d1 = date - tol_d, d2 = date + tol_d)] # non-equi join , on = c("guest_id", "money>=m1", "money<=m2", "date>=d1", "date<=d2"), # aggregate group-wise, grouped by join conditions, prettify result match := .N, by = .EACHI][, match := as.integer(!is.na(match))][]
如果没有非等联接,我们将不得不创建所有可能组合的笛卡尔积,并消除那些与条件不匹配的行。