Использование purrr для применения фильтра и изменения на основе другого набора данных - PullRequest
1 голос
/ 18 марта 2019

Я пытаюсь использовать purrr для применения фильтра и , чтобы изменить переменную, обе на основе значений другого фрейма данных.

# This is the original table
set.seed(100)
dfOriginal <- data.table(age = sample(10:60, 10))

# Following is the second data frame containing one variable which 
# I would like to filter by - age criterion
# and then to mutate with - age band
dfAgeBands <- data.table(ageCriterion = c("age > 0 & age <= 20", "age > 20 & age <= 30"),
              ageBand = c("Young Adults", "Adults"))

finalDf <- map2(dfAgeBands$ageCriterion, dfAgeBands$ageBand, function(x,y){dfOriginal[.x, ageBands := .y]})

Редактировать: просто исправил код (который был построен для другого набора данных!) Но это все равно не работает.

Ожидаемый результат будет таким, как показано ниже, в соответствии с правилами, определенными ageCriterion в dfAgeBands кадре данных.

    age      ageBand
 1:  56         <NA>
 2:  51         <NA>
 3:  41         <NA>
 4:  36         <NA>
 5:  44         <NA>
 6:  32         <NA>
 7:  19 Young Adults
 8:  53         <NA>
 9:  28       Adults
10:  29       Adults

Ответы [ 3 ]

2 голосов
/ 18 марта 2019

решение с использованием неравномерного соединения от data.table ..

сначала укажите минимальный и максимальный возраст для каждой группы, извлеките из описания

library(dplyr)
library(stringr)
#get minimum and maximum age grom group
dfAgebands <- dfAgeBands %>% mutate( minAge = stringr::str_extract( ageCriterion, "(?<=\\> )[0-9]+(?= &)") %>% as.numeric(),
                                     maxAge = stringr::str_extract( ageCriterion, "(?<=\\<= )[0-9]+(?=$)") %>% as.numeric() )
          ageCriterion      ageBand minAge maxAge
1  age > 0 & age <= 20 Young Adults      0     20
2 age > 20 & age <= 30       Adults     20     30

Теперь вы можете легко выполнить неравное объединение

library(data.table)
dfOriginal[ dfAgebands, ageBand := i.ageBand, on = c("age > minAge", "age <= maxAge")]

#     age      ageBand
#  1:  55         <NA>
#  2:  40         <NA>
#  3:  41         <NA>
#  4:  33         <NA>
#  5:  56         <NA>
#  6:  25       Adults
#  7:  11 Young Adults
#  8:  13 Young Adults
#  9:  28       Adults
# 10:  27       Adults
1 голос
/ 18 марта 2019

Для чего это стоит - то есть, мое решение в дополнение к решению гигантов, таких как Акрун, и других гениев, таких как Вимпел, - вот решение с map2:

map2(ageBands$AgeCriteria, ageBands$AgeBand, 
          function(x,y){df1[eval(parse_expr(x)), ageBands := y]})
1 голос
/ 18 марта 2019

Обычно лучше не проходить через eval(parse, но выражение здесь соблазнительно использовать это.Один из вариантов - eval использовать выражение в i, просматривая каждый элемент ageCriterion и присваивая (:=) значение ageBand тем элементам, которые удовлетворяют условию i

*.1007 *

Или используя purrr

library(purrr)
pwalk(dfAgeBands, ~ dfOriginal[eval(parse(text = .x)), ageBand := .y])
dfOriginal[]
#    age      ageBand
# 1:  25       Adults
# 2:  22       Adults
# 3:  37         <NA>
# 4:  12 Young Adults
# 5:  32         <NA>
# 6:  56         <NA>
# 7:  46         <NA>
# 8:  26       Adults
# 9:  33         <NA>
#10:  17 Young Adults
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...