rowwise () выдает ошибку с mean () и sum () - PullRequest
1 голос
/ 05 апреля 2020

Я пытаюсь получить среднее () и сумму () для определенных столбцов в строках. Этот код создаст набор данных:

library(tidyverse)

test_data <- tibble(part_id = 1:5,
                      a_1 = c("a", "b", "c", "d", "a"),
                      a_2 = c("b", NA, "b", "a", "d"),
                      a_3 = c("b", "b", "d", "d", "a"))


test_data <- test_data %>%
  mutate_at(vars(a_1, a_2), .funs = list(scored = ~case_when(
    . == "a" | . == "b" ~ 1,
    . == "c" ~ 0,
    . == "d" ~ -100)))

Если я попытаюсь использовать rowSums () или rowMeans (), я получу правильный ответ:

library(tidyverse)

test_data <- test_data %>%
  mutate(a_total = rowSums(dplyr::select(., contains("scored")), na.rm = TRUE),
         a_mean = rowMeans(dplyr::select(., contains("scored")), na.rm = TRUE))

Но, если попытаться использовать rowwise () с последующим sum () или mean (), он не работает:

library(tidyverse)

test_data <- test_data %>%
  rowwise() %>%
  mutate(a_total = base::sum(dplyr::select(., contains("scored")), na.rm = TRUE),
         a_mean = base::mean(dplyr::select(., contains("scored")), na.rm = TRUE)) %>%
  ungroup()

Для sum () он дает общую сумму, эффективно игнорируя rowwise (), и для mean (), все ответы - NA, и я получаю это предупреждение для каждой строки:

Warning messages:
1: In mean.default(dplyr::select(., contains("scored")), na.rm = TRUE) :
  argument is not numeric or logical: returning NA

Я также попробовал эту модификацию, включив функцию c (), как если бы вы перечисляли каждый столбец. Это привело к следующей ошибке:

library(tidyverse)

test_data <- test_data %>%
  rowwise() %>%
  mutate(a_total = base::sum(c(dplyr::select(., contains("scored"))), na.rm = TRUE),
         a_mean = base::mean(c(dplyr::select(., contains("scored"))), na.rm = TRUE)) %>%
  ungroup()

Error in base::sum(c(dplyr::select(., contains("scored"))), na.rm = TRUE) : 
  invalid 'type' (list) of argument

Как я могу заставить эту работу работать с rowwise ()? Почему это ведет себя не так, как обычно, и чем rowSums () или rowMeans ()?

Я ценю любую информацию!

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Проблема в том, что rowwise выполняет группирование по строкам, а sum, mean et c работают на vector с. Это по существу применяется к одной строке data.frame. Оборачивая unlist, он преобразуется из data.frame в vector

library(dplyr)
test_data <- test_data %>%
                  rowwise() %>%
                  mutate(a_total = base::sum(unlist(dplyr::select(., 
                               contains("scored")), recursive = FALSE), na.rm = TRUE),
                         a_mean = base::mean(unlist(dplyr::select(., 
                               contains("scored")), recursive = FALSE), na.rm = TRUE)) %>%
                   ungroup()

Или используйте pmap

library(purrr)
test_data  %>%
   mutate(a_total = pmap_dbl(select(., contains("scored")),
                    ~ sum(c(...), na.rm = TRUE)),
          a_mean =  pmap_dbl(select(., contains("scored")),
                    ~ mean(c(...), na.rm = TRUE)))
0 голосов
/ 05 апреля 2020

Вот другой подход, если вы хотите придерживаться rowwise(), который использует {rlang} для захвата переменных, которые вы хотите суммировать и усреднить:

library(dplyr)

test_data <- tibble(part_id = 1:5,
                    a_1 = c("a", "b", "c", "d", "a"),
                    a_2 = c("b", NA, "b", "a", "d"),
                    a_3 = c("b", "b", "d", "d", "a"))


test_data <- test_data %>%
  mutate_at(vars(a_1, a_2), .funs = list(scored = ~case_when(
    . == "a" | . == "b" ~ 1,
    . == "c" ~ 0,
    . == "d" ~ -100)))


# Get the names of the variables you want
vars <- test_data %>% select(contains("scored")) %>% names()

# Use `rlang` so that `dplyr` will recognize the variable names
test_data %>%
  rowwise() %>%
  mutate(a_sum = sum(c(!!!rlang::syms(vars)), na.rm = TRUE),
         a_mean = mean(c(!!!rlang::syms(vars)), na.rm = TRUE)) %>% 
  ungroup()
#> # A tibble: 5 x 8
#>   part_id a_1   a_2   a_3   a_1_scored a_2_scored a_sum a_mean
#>     <int> <chr> <chr> <chr>      <dbl>      <dbl> <dbl>  <dbl>
#> 1       1 a     b     b              1          1     2    1  
#> 2       2 b     <NA>  b              1         NA     1    1  
#> 3       3 c     b     d              0          1     1    0.5
#> 4       4 d     a     d           -100          1   -99  -49.5
#> 5       5 a     d     a              1       -100   -99  -49.5

Создано в 2020-04-05 представителем пакета (v0.3.0)

...