[英]Any difference between dplyr::across and purrr::modify_if/at?
如果想將一個函數應用於一個或多個列,可選地基於某些標准,似乎有兩種相同的方法可以使用 Tidyverse 包來做到這一點。 我想知道是否有任何理由更喜歡其中一個?
例如,如果想要將所有數字列轉換為字符,您可以執行以下任一操作:
library(dplyr, warn.conflicts = FALSE)
library(purrr)
library(ggplot2)
mpg |>
mutate(across(where(is.numeric), as.character)) |>
slice_head(n = 5)
#> # A tibble: 5 × 11
#> manufacturer model displ year cyl trans drv cty hwy fl class
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compa…
#> 2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compa…
#> 3 audi a4 2 2008 4 manual(m6) f 20 31 p compa…
#> 4 audi a4 2 2008 4 auto(av) f 21 30 p compa…
#> 5 audi a4 2.8 1999 6 auto(l5) f 16 26 p compa…
mpg |>
modify_if(is.numeric, as.character) |>
slice_head(n = 5)
#> # A tibble: 5 × 11
#> manufacturer model displ year cyl trans drv cty hwy fl class
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compa…
#> 2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compa…
#> 3 audi a4 2 2008 4 manual(m6) f 20 31 p compa…
#> 4 audi a4 2 2008 4 auto(av) f 21 30 p compa…
#> 5 audi a4 2.8 1999 6 auto(l5) f 16 26 p compa…
或者,如果您只想更改年份列,則以下任一方法都可以:
library(dplyr, warn.conflicts = FALSE)
library(purrr)
library(ggplot2)
mpg |>
mutate(year = as.character(year)) |>
slice_head(n = 5)
#> # A tibble: 5 × 11
#> manufacturer model displ year cyl trans drv cty hwy fl class
#> <chr> <chr> <dbl> <chr> <int> <chr> <chr> <int> <int> <chr> <chr>
#> 1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compa…
#> 2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compa…
#> 3 audi a4 2 2008 4 manual(m6) f 20 31 p compa…
#> 4 audi a4 2 2008 4 auto(av) f 21 30 p compa…
#> 5 audi a4 2.8 1999 6 auto(l5) f 16 26 p compa…
mpg |>
modify_at('year', as.character) |>
slice_head(n = 5)
#> # A tibble: 5 × 11
#> manufacturer model displ year cyl trans drv cty hwy fl class
#> <chr> <chr> <dbl> <chr> <int> <chr> <chr> <int> <int> <chr> <chr>
#> 1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compa…
#> 2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compa…
#> 3 audi a4 2 2008 4 manual(m6) f 20 31 p compa…
#> 4 audi a4 2 2008 4 auto(av) f 21 30 p compa…
#> 5 audi a4 2.8 1999 6 auto(l5) f 16 26 p compa…
除了可能不必額外導入 purrr 之外,是否有任何理由更喜歡其中一個? 還是這些相同?
我不確定這是唯一的區別,但mutate
只能在data.frame
上運行,而modify_if
也可以在list
上運行。
library(dplyr)
library(purrr)
list(a=1, b="b") %>% modify_if(is.numeric, `+`, 1)
# $a
# [1] 2
# $b
# [1] "b"
list(a=1, b="b") %>% mutate(across(where(is.numeric), ~ . + 1))
# Error in UseMethod("mutate") :
# no applicable method for 'mutate' applied to an object of class "list"
雖然您已經證明,給定繼承data.frame
的輸入,兩者都應該產生相同的輸出。
identical(
iris %>% modify_if(is.numeric, `+`, 1),
iris %>% mutate(across(where(is.numeric), ~ . + 1))
)
# [1] TRUE
不過有趣的是, modify_if
的速度要快得多:
bench::mark(
purrr = iris %>% modify_if(is.numeric, `+`, 1),
dplyr = iris %>% mutate(across(where(is.numeric), ~ . + 1))
)
# # A tibble: 2 x 13
# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time result memory time gc
# <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm> <list> <list> <list> <list>
# 1 purrr 220us 254.5us 3816. 4.88KB 2.65 1440 1 377ms <df [150 x 5]> <Rprofmem [4 x 3]> <benc~ <tibb~
# 2 dplyr 1.58ms 1.91ms 515. 11.34KB 2.50 206 1 400ms <df [150 x 5]> <Rprofmem [19 x 3]> <benc~ <tibb~
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.