left_join по категориям и значениям диапазона - PullRequest
0 голосов
/ 18 сентября 2018

Я хочу left_join два кадра данных.

pensions <- data.frame(gender = c(rep("Female", 3 ), (rep("Male", 2 ) )), 
                   age = c(66,69,72,85,62), 
                   type = c(rep("widow",2), rep("disability", 2 ), "old age"))




gender  <- c(rep("Female", 12), rep("Male", 12))
type    <- rep(c(rep("widow",4), rep("disability",4), rep("old_age",4)),2)
min_age <- rep(c(65,seq(76, 99, by = 10)),6)
max_age <- rep(c(seq(75, 99, by = 10),99),6)
factor   <- c(435,215,415,89,10,45,36,74,98,15,27,23,
         117,343,201,58,41,95,777,65,21,57,13,6)


pension_factors <- data.frame(gender, type, min_age, max_age, factor )

Первый кадр данных пенсии содержит столбцы пол , возраст и тип . Последний пересматривает тип пенсии.

Второй кадр данных pension_factors содержит столбцы пол , тип , min_age , max_age и коэффициент .

Как мне left_join пенсии с Pension_factors таким образом, что я left_join по пол и типа и возраст pensions$age равен или больше pension_factors$min_age, но меньше или равен pension_factors$max_age?

Ответы [ 3 ]

0 голосов
/ 18 сентября 2018

Мы могли бы использовать fuzzyjoin:

library(fuzzyjoin)
library(tidyverse)
fuzzy_left_join(
    pensions %>% mutate_if(is.factor, as.character),
    pension_factors %>% mutate_if(is.factor, as.character),
    by = c(
        "gender" = "gender",
        "type" = "type",
        "age" = "min_age",
        "age" = "max_age"),
    match_fun = c(`==`, `==`, `>=`, `<=`))
#  gender.x age     type.x gender.y     type.y min_age max_age factor
#1   Female  66      widow   Female      widow      65      75    435
#2   Female  69      widow   Female      widow      65      75    435
#3   Female  72 disability   Female disability      65      75     10
#4     Male  85 disability     Male disability      76      85     95
#5     Male  62    old age     <NA>       <NA>      NA      NA     NA

Объяснение: by перечисляет все столбцы, по которым мы сопоставляем, а match_fun перечисляет соответствующие условия сопоставления.

0 голосов
/ 18 сентября 2018

Вы можете сначала объединить два набора данных:

mergeddf<-merge(x=pensions,y=pension_factors,by.x=c("gender", "type"),by.y=c("gender", "type"),all.x = TRUE)

тогда возьмите только подмножество объединенного набора данных, в котором возраст находится между минимальным и максимальным возрастом:

finaldf<-mergeddf[which(mergeddf$age>=mergeddf$min_age & mergeddf$age<=mergeddf$max_age),]
     #  gender       type age min_age max_age factor
     #1 Female disability  72      65      75     10
     #5 Female      widow  66      65      75    435
     #9 Female      widow  69      65      75    435
     #14  Male disability  85      76      85     95
0 голосов
/ 18 сентября 2018

Вы должны иметь возможность присоединиться, а затем отфильтровать объединенный фрейм данных:

library(dplyr)

left_join(pensions, pension_factors, by=c('gender', 'type')) %>%
    filter(age >= min_age,
           age <= max_age)

  gender age       type min_age max_age factor
1 Female  66      widow      65      75    435
2 Female  69      widow      65      75    435
3 Female  72 disability      65      75     10
4   Male  85 disability      76      85     95
...