Суммируйте, но сохраняйте переменную длины (dplyr)

Основной вопрос dplyr ... Респонденты могли выбрать несколько компаний, которые они используют. Например:

library(dplyr)
test <- tibble(
 CompanyA = rep(c(0:1),5),
 CompanyB = rep(c(1),10),
 CompanyC = c(1,1,1,1,0,0,1,1,1,1)
)
test

Если бы это был вопрос с принудительным выбором, то есть респонденты могли бы сделать только один выбор, я бы сделал следующее для базовой сводной таблицы:

test %>% 
  summarise_all(funs(sum), na.rm = TRUE) %>% 
  gather(Response, n) %>% 
  arrange(desc(n)) %>% 
  mutate("%" = round(100*n/sum(n)))

Обратите внимание, однако, что столбец «%» - это не то, что мне нужно. Вместо этого я ищу долю от общего числа респондентов для каждого отдельного варианта ответа (поскольку они могут выбрать несколько вариантов).

Я пробовал добавить mutate(totalrows = nrow(.)) %>% перед командой summarise_all. Это позволило бы мне использовать эту переменную в качестве знаменателя в более поздней команде mutate. Однако summarise_all исключает переменную totalrows.

Кроме того, если есть лучший способ сделать это, я открыт для идей.


person Daniel    schedule 10.10.2018    source источник
comment
Я не уверен, что понимаю ваш вопрос, но не могли бы вы просто взять среднее значение каждого столбца, чтобы получить долю от общего числа респондентов для каждого отдельного варианта ответа? Я имею в виду, что если 3 человека из 5 выберут компанию A, ваши данные могут выглядеть как c(1, 0, 1, 1, 0). Если вы возьмете среднее значение, это 0,6, то есть доля респондентов, выбравших этот вариант.   -  person tblznbits    schedule 10.10.2018
comment
Это полностью работает - я слишком много думал об этом. Пожалуйста, перейдите к ответу, и я приму его.   -  person Daniel    schedule 10.10.2018
comment
Если вы хотите и дальше думать об этом, вы можете изменить sum(n) на nrow(test), так что код будет test %>% summarise_all(funs(sum), na.rm = TRUE) %>% gather(Response, n) %>% arrange(desc(n)) %>% mutate("%" = round(100*n/nrow(test)))   -  person Kerry Jackson    schedule 10.10.2018


Ответы (3)


Чтобы получить долю респондентов, которые выбрали вариант, когда эта переменная является двоичной, вы можете взять среднее значение. Чтобы сделать это с вашими тестовыми данными, вы можете использовать sapply:

sapply(test, mean)
CompanyA CompanyB CompanyC 
     0.5      1.0      0.8 

Если вы хотите сделать это более сложным образом (скажем, ваши данные не закодированы в двоичном формате, а вместо этого хранятся как 1 и 2), вы можете сделать это следующим образом:

test %>% 
    gather(key='Company') %>% 
    group_by(Company) %>% 
    summarise(proportion = sum(value == 1) / n())

# A tibble: 3 x 2
  Company  proportion
  <chr>         <dbl>
1 CompanyA        0.5
2 CompanyB        1  
3 CompanyC        0.8
person tblznbits    schedule 10.10.2018
comment
Я не знал этого о варах, закодированных как 1 или 2. Спасибо! - person Daniel; 10.10.2018

Если вы поместите все функции в список в суммировании, это сработает. Однако после этого вам нужно будет немного навести порядок.

test %>% 
  summarise_all(
    list(
      rows = length,
      n = function(x){sum(x, na.rm = T)},
      perc = function(x){sum(x,na.rm = T)/length(x)}
    )) %>%
  tidyr::gather(Response, n) %>%
  tidyr::separate(Response, c("Company", "Metric"), '_') %>%
  tidyr::spread(Metric, n)

И ты получишь это

  Company      n  perc  rows
  <chr>    <dbl> <dbl> <dbl>
1 CompanyA     5   0.5    10
2 CompanyB    10   1      10
3 CompanyC     8   0.8    10
person struggles    schedule 10.10.2018

Вот решение с использованием tidyr::gather:

test %>% 
  gather(Company, response) %>% 
  group_by(Company) %>% 
  summarise(`%` = 100 * sum(response) / n())
person DiceboyT    schedule 10.10.2018