Эквивалент Vlookup () в Dplyr - PullRequest
0 голосов
/ 29 мая 2020

Мой df выглядит так:

library(tidyverse) 
df_1 <- tibble::tribble(
          ~sub_date, ~value_1, ~value_2,
          "2020-05",       58,      130,
          "2020-05",       58,       "check",
          "2020-03",       50,      120,
          "2020-03",       55,       "check",
          "2020-03",       55,       "check"
          )

Я хочу изменить значения строк, содержащих «check», на эталонные значения здесь:

df_ref <- tibble::tribble(
            ~sub_date, ~ref_value,
            "2020-05",        123,
            "2020-03",        234
            )

В основном - используя df_ref таблица как справочная только для строк, содержащих проверку.

Я хочу использовать эквивалент функции lookup () в excel, который используется в функции if ().

Конечный результат :

df_final <- tibble::tribble(
              ~sub_date, ~value_1, ~value_2,
              "2020-05",       58,      130,
              "2020-05",       58,      123,
              "2020-03",       50,      120,
              "2020-03",       55,      234,
              "2020-03",       55,      234
              )

Ответы [ 4 ]

1 голос
/ 29 мая 2020

Этот код должен работать

df_1 %>% 
  mutate(value_2 = as.numeric(na_if(value_2, "check"))) %>% 
  left_join(df_ref, by = "sub_date") %>% 
  mutate(value_2 = coalesce(value_2, ref_value)) %>% 
  select(-ref_value)

Небольшое пояснение: сначала мы устанавливаем NA все значения "check" благодаря na_if, затем мы присоединяемся к таблице поиска, затем мы coalesce два столбца value_2 и ref_value, т.е. возьмите первое не пропущенное значение между двумя.


Вывод

# A tibble: 5 x 3
#   sub_date value_1 value_2
#   <chr>      <dbl>   <dbl>
# 1 2020-05       58     130
# 2 2020-05       58     123
# 3 2020-03       50     120
# 4 2020-03       55     234
# 5 2020-03       55     234

Небольшое примечание: ваш df_1 не работает, если вы вставили его в свой вопрос. Ниже я настроил его значения как символ, чтобы он работал

df_1 <- tibble::tribble(
  ~sub_date, ~value_1, ~value_2,
  "2020-05",       58,      "130",
  "2020-05",       58,      "check",
  "2020-03",       50,      "120",
  "2020-03",       55,      "check",
  "2020-03",       55,      "check"
)
0 голосов
/ 29 мая 2020

Вы также можете просто сделать это одной строкой с ifelse и match, поскольку мы действительно не заинтересованы в объединении фреймов данных. Оберните его в as.numeric, если хотите, чтобы вывести числовой c.

library(dplyr)

mutate(df_1, 
       value_2 = ifelse(value_2 == "check", 
                        df_ref$ref_value[match(sub_date, df_ref$sub_date)],
                        value_2))
0 голосов
/ 29 мая 2020

Использование базы R:

ref_lut <- with(df_ref, setNames(ref_value, sub_date))

df_1$value_2 <- 
  ifelse(df_1$value_2 == "check", ref_lut[df_1$sub_date], df_1$value_2)

df_1

  sub_date value_1 value_2
  <chr>      <dbl> <chr>  
1 2020-05       58 130    
2 2020-05       58 123    
3 2020-03       50 120    
4 2020-03       55 234    
5 2020-03       55 234    
0 голосов
/ 29 мая 2020

Удачи, когда есть несколько совпадений

library(tidyverse)
df_1 <- tibble::tribble(
  ~sub_date, ~value_1, ~value_2,
  "2020-05",       58,      "130",
  "2020-05",       58,       "check",
  "2020-03",       50,      "120",
  "2020-03",       55,       "check",
  "2020-03",       55,       "check"
)

df_ref <- tibble::tribble(
  ~sub_date, ~ref_value,
  "2020-05",        123,
  "2020-03",        234
)

df_1 %>% 
  left_join(df_ref) %>%
  mutate(value_2_true = ifelse(value_2 == "check",ref_value,value_2)) %>%
  mutate(value_2 = value_2_true %>% as.numeric()) %>% 
  select(-value_2_true,-ref_value)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...