使用purrr:pmap_dbl计算多列(列数未知)每行的平均值

5

我希望能够:

(1) 编写一个简单的函数来计算字符串向量的平均长度

(2) 选择数据框中的多个字符串列,对每一行计算字符串长度的平均值

(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))

但我尤其担心以下两点:

  1. 我是否真的需要如此复杂的函数?有没有更简单的方法?

  2. 我是否真的需要使用select来选择我的多列数据?有没有类似vars(matches("q"))或者q0:q3这样的tidyselect魔法可以解决呢?(它们不行...)

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.

请注意存在多个q列,因此使用list(q0, q1, q2)选择它们太长了,或者假设我事先不知道有多少q列。


这里需要使用 select - akrun
1个回答

2

仅使用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 

如果您只想要以 q 开头的列:

df %>%
 mutate(avg_len = rowMeans(select(., starts_with("q")) %>%
                            mutate_all(nchar), na.rm = TRUE))

1
感谢@tmfmnk。也许这是个人口味的问题,但我真的很喜欢pmap_dbl方法。似乎很奇怪,没有办法使用tidyselect魔法指定一堆列给pmap。我们两个本质上在管道内创建了另一个数据框。我想我们已经被宠坏了。 - Giora Simchoni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接