我希望能够:
(1) 编写一个简单的函数来计算字符串向量的平均字符串长度
(2) 在 data.frame 中选择一堆多个字符串列来计算每行的字符串长度平均值
(3) 使用我的函数purrr::pmap_dbl
我能够通过以下方式执行(1)、(2)和(3):
library(tidyverse)
df <- tibble(q0 = c("a", "b", "c"),
q1 = c("aa", "bb", "cc"),
q2 = c("aaa", "b", NA),
some_other_var = 1:3)
avg_str_len <- function(...) mean(str_length(c(...)), na.rm = TRUE)
df %>%
mutate(avg_len = pmap_dbl(select(., q0:q2), avg_str_len))
## A tibble: 3 x 5
# q0 q1 q2 some_other_var avg_len
# <chr> <chr> <chr> <int> <dbl>
#1 a aa aaa 1 2
#2 b bb b 2 1.33
#3 c cc NA 3 1.5
# or if I don't know how many q columns:
df %>%
mutate(avg_len = pmap_dbl(select(., starts_with("q")), avg_str_len))
Run Code Online (Sandbox Code Playgroud)
但我分别特别担心(1)和(2):
我真的需要这么复杂的功能吗?难道就没有更简单的方法吗?
我真的需要select选择多个列吗?是不是有一些类似或之类tidyselect的魔法可以发挥作用?(他们不……)vars(matches("q"))q0:q3
df %>%
mutate(avg_len = pmap_dbl(q0:q2, avg_str_len))
#Error in q0:q2 : NA/NaN argument
#In addition: Warning messages:
#1: In q0:q2 : numerical expression has 3 elements: only the first used
#2: In q0:q2 : numerical expression has 3 elements: only the first used
#3: In is.data.frame(.l) : NAs introduced by coercion
#4: In is.data.frame(.l) : NAs introduced by coercion
df %>%
mutate(avg_len = pmap_dbl(vars(matches("q")), avg_str_len))
#Error: Element 1 of `.l` must be a vector, not a `quosure/formula` object
#Call `rlang::last_error()` to see a backtrace.
Run Code Online (Sandbox Code Playgroud)
请注意,有多个q列,因此使用它们选择它们list(q0, q1, q2)太长,或者假设我事先不知道q我有多少列
一种仅涉及的选项dplyr可能是:
df %>%
mutate(avg_len = rowMeans(select_if(., is_character) %>%
mutate_all(nchar), na.rm = TRUE))
q0 q1 q2 some_other_var avg_len
<chr> <chr> <chr> <int> <dbl>
1 a aa aaa 1 2
2 b bb b 2 1.33
3 c cc <NA> 3 1.5
Run Code Online (Sandbox Code Playgroud)
或者,如果您只想要以 开头的列q:
df %>%
mutate(avg_len = rowMeans(select(., starts_with("q")) %>%
mutate_all(nchar), na.rm = TRUE))
Run Code Online (Sandbox Code Playgroud)