#r #dplyr
Вопрос:
Tidyverse значительно упрощает управление данными, и я благодарен разработчикам, которые сделали это. Я знаком с основными функциями dplyr, такими как group_by
, filter
, select
, и mutate
. Тем не менее, иногда я хочу управлять данными, когда есть подмножество данных.
Используя starwars
набор данных dplyr в качестве примера, ниже приведены две задачи, которыми я знаю, как управлять с помощью базы R. Интересно, каковы эквиваленты tidyverse?
library(dplyr, warn.conflicts = FALSE)
data(starwars)
dim(starwars)
#> [1] 87 14
В starwars
наборе данных предположим, что персонал ввода данных допустил ошибку в двух домашних мирах.
Задача 1: На родине Татуина цвет волос для всех персонажей ростом не менее 160 см должен быть «светлым». Это легко сделать в базе R, но каков эквивалент tidyverse?
starwars[starwars$homeworld == "Tatooine" amp; starwars$height >160,
"hair_color",
drop = TRUE
] <- "blond"
Задача 2: Немного сложнее. Предположим, что на Набу (родной мир) была допущена ошибка, когда недостающая масса составляла 80 кг, и мы хотим исключить виды гунганов на родной планете из набора данных. Я также хочу подсчитать количество строк, используемых только для родного мира Набу. В базе R это просто, но из-за существенного управления данными мне нужно назначить промежуточный объект.
# Make a subset for those from Naboo homeworld and delete from main dataset
starwars.Naboo <- starwars %>% filter(homeworld == "Naboo")
starwars <- starwars %>% filter(homeworld != "Naboo")
# Manage the subset of starwars.Naboo
starwars.Naboo <- starwars.Naboo %>%
filter(species != "Gungan") %>%
mutate(mass = coalesce(mass, 80)) %>%
mutate(num = n())
# Re-add starwars.Naboo. num should be missing for all other homeworlds.
starwars2 <- bind_rows(starwars, starwars.Naboo)
# Check to ensure transformation works
starwars2 %>%
tail(n = 15) %>%
print(width = Inf)
#> # A tibble: 15 x 15
#> name height mass hair_color skin_color eye_color
#> <chr> <int> <dbl> <chr> <chr> <chr>
#> 1 Ratts Tyerell 79 15 none grey, blue unknown
#> 2 Wat Tambor 193 48 none green, grey unknown
#> 3 San Hill 191 NA none grey gold
#> 4 Shaak Ti 178 57 none red, blue, white black
#> 5 Grievous 216 159 none brown, white green, yellow
#> 6 Tarfful 234 136 brown brown blue
#> 7 Raymus Antilles 188 79 brown light brown
#> 8 Sly Moore 178 48 none pale white
#> 9 Tion Medon 206 80 none grey black
#> 10 R2-D2 96 32 <NA> white, blue red
#> 11 Palpatine 170 75 grey pale yellow
#> 12 Gregar Typho 185 85 black dark brown
#> 13 Cordé 157 80 brown light brown
#> 14 Dormé 165 80 brown light brown
#> 15 Padmé Amidala 165 45 brown light brown
#> birth_year sex gender homeworld species films vehicles starships
#> <dbl> <chr> <chr> <chr> <chr> <list> <list> <list>
#> 1 NA male masculine Aleen Minor Aleena <chr [1]> <chr [0]> <chr [0]>
#> 2 NA male masculine Skako Skakoan <chr [1]> <chr [0]> <chr [0]>
#> 3 NA male masculine Muunilinst Muun <chr [1]> <chr [0]> <chr [0]>
#> 4 NA female feminine Shili Togruta <chr [2]> <chr [0]> <chr [0]>
#> 5 NA male masculine Kalee Kaleesh <chr [1]> <chr [1]> <chr [1]>
#> 6 NA male masculine Kashyyyk Wookiee <chr [1]> <chr [0]> <chr [0]>
#> 7 NA male masculine Alderaan Human <chr [2]> <chr [0]> <chr [0]>
#> 8 NA <NA> <NA> Umbara <NA> <chr [2]> <chr [0]> <chr [0]>
#> 9 NA male masculine Utapau Pau'an <chr [1]> <chr [0]> <chr [0]>
#> 10 33 none masculine Naboo Droid <chr [7]> <chr [0]> <chr [0]>
#> 11 82 male masculine Naboo Human <chr [5]> <chr [0]> <chr [0]>
#> 12 NA male masculine Naboo Human <chr [1]> <chr [0]> <chr [1]>
#> 13 NA female feminine Naboo Human <chr [1]> <chr [0]> <chr [0]>
#> 14 NA female feminine Naboo Human <chr [1]> <chr [0]> <chr [0]>
#> 15 46 female feminine Naboo Human <chr [3]> <chr [0]> <chr [3]>
#> num
#> <int>
#> 1 NA
#> 2 NA
#> 3 NA
#> 4 NA
#> 5 NA
#> 6 NA
#> 7 NA
#> 8 NA
#> 9 NA
#> 10 6
#> 11 6
#> 12 6
#> 13 6
#> 14 6
#> 15 6
Session_info
xfun::session_info("dplyr")
#> R version 4.0.4 (2021-02-15)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 19041)
#>
#> Locale:
#> LC_COLLATE=English_United States.1252
#> LC_CTYPE=English_United States.1252
#> LC_MONETARY=English_United States.1252
#> LC_NUMERIC=C
#> LC_TIME=English_United States.1252
#>
#> Package version:
#> cli_2.5.0 crayon_1.4.1 **dplyr_1.0.5** ellipsis_0.3.2
#> fansi_0.5.0 generics_0.1.0 glue_1.4.2 graphics_4.0.4
#> grDevices_4.0.4 lifecycle_1.0.0 magrittr_2.0.1 methods_4.0.4
#> pillar_1.6.1 pkgconfig_2.0.3 purrr_0.3.4 R6_2.5.0
#> rlang_0.4.11 stats_4.0.4 tibble_3.1.2 tidyselect_1.1.0
#> utf8_1.2.1 utils_4.0.4 vctrs_0.3.8
ПРАВКА 1: Для задачи 2 могу ли я избежать назначения промежуточного объекта в tidyverse? Есть ли более элегантный способ использовать это в приведенном выше коде?
Комментарии:
1. Вы что-то скопировали и вставили сюда? Я действительно не могу понять, в чем вопрос!
2. @Serkan: Для задачи 2 могу ли я избежать назначения промежуточного объекта в tidyverse? Есть ли более элегантный способ использовать это в приведенном выше коде?
3. Я почти уверен, что это возможно. Неужели приведенных ниже ответов недостаточно? Если это не так, вам нужно будет более четко сформулировать свой вопрос. Я все еще не совсем понимаю эту идею.
Ответ №1:
Похоже, вы уже сделали 2?
starwars %>%
mutate(
hair_color = if_else(homeworld == "Tatooine" amp; height >160, "blond", hair_color)
)
Комментарии:
1. Это задача 1. Спасибо. Эквивалентно основанию R
r starwars[starwars$homeworld == "Tatooine" amp; starwars$height >160, "hair_color", drop = TRUE ] <- "blond"
Ответ №2:
Ваше второе задание может быть выполнено в одной трубе
starwars %>%
filter(homeworld == "Naboo",
species != "Gungan") %>%
mutate(mass = coalesce(mass, 80),
num = n()) %>%
bind_rows(starwars %>% filter(homeworld != "Naboo"))