Можете ли вы изменить более одного столбца на основе значения другого столбца в тиббле, указав условие только один раз? - PullRequest
2 голосов
/ 26 мая 2020

Предположим, у меня есть следующая таблица:

library(tidyverse)
foods <- tibble(
  name  = c("apple", "carrot", "broccoli", "pear", "carrot", "broccoli"),
  color = c("red", "orange", "purple", "green", "orange", "purple"),
  type  = c("fruit", "veggie", "fruit", "fruit", "veggie", "fruit")
)

> foods
# A tibble: 6 x 3
  name     color  type  
  <chr>    <chr>  <chr> 
1 apple    red    fruit 
2 carrot   orange veggie
3 broccoli purple fruit 
4 pear     green  fruit 
5 carrot   orange veggie
6 broccoli purple fruit

Как видите, цвет и тип брокколи здесь неверны. Я могу исправить это, изменив цвет и тип по отдельности, например:

> foods %>% 
+   mutate(color = if_else(name == "broccoli", "green", color),
+          type  = if_else(name == "broccoli", "veggie", type))
# A tibble: 6 x 3
  name     color  type  
  <chr>    <chr>  <chr> 
1 apple    red    fruit 
2 carrot   orange veggie
3 broccoli green  veggie
4 pear     green  fruit 
5 carrot   orange veggie
6 broccoli green  veggie

В этом примере мое решение в основном хорошее, но повторение условия if_else становится раздражающим, если вы пытаетесь изменить много столбцов в один раз. Есть ли способ указать условие один раз и изменить несколько столбцов? Я немного покопался, но не могу найти этот вопрос раньше - я уверен, что его задавали, я, вероятно, просто неправильно формулирую свой поиск. Так что не стесняйтесь указывать мне в этом направлении. Я бы предпочел решение dplyr / tidyverse, поскольку это то, с чем я знаком, но другие решения тоже могут быть полезны. Спасибо.

Ответы [ 2 ]

0 голосов
/ 27 мая 2020

Важно ли, чтобы брокколи появлялась в тубе дважды? Или вы просто хотите обновить? Если последнее

updateFoods <- tibble(
  name = c("broccoli", "eggplant"),
  color = c("green", "purple"),
  type = c("veggie","veggie")
)

foods %>% 
  rbind(updateFoods) %>% 
  group_by(name) %>% 
  summarise_all(~ last(.))

# A tibble: 5 x 3
  name     color  type  
  <chr>    <chr>  <chr> 
1 apple    red    fruit 
2 broccoli green  veggie
3 carrot   orange veggie
4 eggplant purple veggie
5 pear     green  fruit 
0 голосов
/ 26 мая 2020

Если у нас есть другие значения для обновления, map2 будет лучше

library(dplyr)
library(purrr)
map2_dfc(c('color', 'type'), c('green', 'veggie'), 
       ~ {v1 <- .y
          foods %>% 
               transmute_at(vars(.x), ~ replace(., name == 'broccoli', v1))})%>%
    bind_cols(foods %>% 
               select(name), .)
...