#r #dataframe #merge
#r #фрейм данных #объединить
Вопрос:
У меня есть два фрейма данных (скажем, DF1 и DF2). Я хочу объединить их на основе нескольких критериев. Если «штат» и «город» DF1 совпадают с DF2, а «дата» DF2 находится в пределах четырех лет от «даты» DF1, то я хотел бы добавить столбец «margin» из DF2 в DF1. Если условия не будут выполнены, столбец ‘margin’ DF1 будет иметь значение NA.
DF1 <- structure(list(date = c("2001-02-14", "2001-06-14", "2004-03-31",
"2003-03-11", "2003-06-29"), state = c("DE", "NY", "NY", "NY",
"AZ"), city = c("Wilmington", "New York", "Buffalo", "New York",
"Phoenix"), industry = c("Retail", "Computers and Software",
"Manufacturing (Misc.)", "Healthcare and Medical", "Construction and Supplies"
), SIC = c(5331, 3571, 2541, 8063, 2421)), row.names = c(2937L,
2817L, 2117L, 2298L, 2228L), class = "data.frame")
DF2 <- structure(list(date = c("2000-11-07", "2000-11-07", "2008-11-04",
"2000-11-07", "2000-11-07", "2008-11-04", "2004-11-02", "2004-11-02",
"2008-11-04", "2012-11-06"), state = c("MA", "NY", "OH", "VA",
"CA", "DE", "NY", "NY", "NY", "AZ"), city = c("Boston", "New York",
"Cleveland", "Richmond", "Los Angeles", "Wilmington", "New York",
"Buffalo", "New York", "Phoenix"), margin = c(-3.61895488477766, -41.5805022156573, -40.2049010106604,
24.8839947364776, 17.2042747593408, -55.4514285714286, -35.5094126201826,
-61.9743406985032, -39.9718177548145, 7.47655435915248)), row.names = c(9849L,
10041L, 29268L, 11941L, 7365L, 31116L, 13227L, 17397L, 23352L,
32571L), class = "data.frame")
Комментарии:
1. В вашем примере все даты находятся в пределах 4 лет
2. также
merge
ссылается ли столбецmargin
? оба требуют уточнения3. Спасибо @akrun. В моей выборке много наблюдений, поэтому мне пришлось взять случайную выборку. В этой случайной выборке даты могут быть в пределах 4 лет, но в целом это не так.
4. Спасибо @EJJ. Я исправил опечатку.
Ответ №1:
Что-то вроде этого? В зависимости от того, как вы хотите интервал.
library(lubridate)
library(fuzzyjoin)
DF1$date <- ymd(DF1$date)
DF2$date <- ymd(DF2$date)
DF2$interval <- interval(DF2$date, DF2$date years(4))
fuzzy_left_join(DF1, DF2,
by = c("city" = "city",
"state" = "state",
"date" = "interval"),
match_fun = c(`==`, `==`, `%within%`))
Комментарии:
1. Спасибо @gravertje. С небольшими исправлениями это работает.