Как рассчитать суммы строк или количество выбранных столбцов с условием, используя Tidyverse? - PullRequest
0 голосов
/ 24 ноября 2018

У меня есть следующий фрейм данных (который является подмножеством большего фрейма данных с> 3000 obs с 2 различными уровнями года):

rp.pptn <- data.frame(id = c("150015", "150016", "150017", "150018", 
"150019", "150020"), year = structure(c(1L, 1L, 1L, 1L, 1L, 1L),
.Label = c("15", "18"), class = "factor"), 
freqtools = c(1, 1, 2, 1, 1, 3), freqtrees = c(2, 3, 3, 5, 4, 3), 
freqrt = c(2, 2, 2, 2, 1, 3), freqroamfriends = c(1, 1, 1, 3, 1, 1), 
freqroamalone = c(1, 1, 1, 2, 1, 1), freqparts = c(2, 2, 2, 2, 3, 3), 
freqmessy = c(5, 5, 2, 5, 4, 5), freqride = c(3, 1, 2, 5, 3, 3), 
freqrain = c(1, 3, 2, 3, 1, 3))

Я хотел бы count значения вcols c(3:11), которые удовлетворяют условию.Я пытался использовать rowSums, потому что, когда у меня нет id или группирующей переменной, year, rowSums на самом деле дает мне счет следующим образом:

rp.pptn.no.id <- rp.pptn %>%
   select(c(3:11)) %>%
   mutate(pptnlow = rowSums(pptnrp == 1 | pptnrp == 2 | pptnrp == 6))

Я также смог вычислить rowSums для выбранных столбцов следующим образом:

rp.pptn <- rp.pptn %>% 
   mutate(pptnlow = rowSums(.[c(3:11)]))

Однако, учитывая, что мне нужны id и year для последующего анализа, я хотел бы выполнить оба эти действия за один раз.Меня интересует, почему, учитывая, что мои данные являются числовыми, rowSums в первом случае дает мне количество, а не суммы.Я действительно хотел бы подсчитать, то есть сколько столбцов соответствуют моим критериям

Поиск заставил меня подумать, что что-то, основанное на этом, может сработать:

rp.pptn <- rp.pptn %>% 
  mutate(pptnlow = rowSums(. [3:11]) %in% c(1, 2, 6))

Возвращает логический вектор = FALSE, возможно потому, что что-то в моем состоянии не выполнено.Я не думаю, что я сильно скучаю, но в конечном итоге мне хотелось бы получить следующее:

rp.pptn <- data.frame(id = c("150015", "150016", "150017", "150018", 
"150019", "150020"), year = structure(c(1L, 1L, 1L, 1L, 1L, 1L), 
.Label = c("15", "18"), class = "factor"), 
freqtools = c(1, 1, 2, 1, 1, 3), freqtrees = c(2, 3, 3, 5, 4, 3), 
freqrt = c(2, 2, 2, 2, 1, 3), freqroamfriends = c(1, 1, 1, 3, 1, 1), 
freqroamalone = c(1, 1, 1, 2, 1, 1), freqparts = c(2, 2, 2, 2, 3, 3), 
freqmessy = c(5, 5, 2, 5, 4, 5), freqride = c(3, 1, 2, 5, 3, 3), 
freqrain = c(1, 3, 2, 3, 1, 3), pptnlow = c(7, 6, 8, 4, 5, 2))

Как уже упоминалось, мой фактический набор данных намного больше, поэтому чем больше автоматизации, тем лучше!Спасибо.

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

Мы можем использовать mutate_at для замены значения, основанного на условии (1, 2, 6), на TRUE или FALSE, использовать rowSums, а затем привязать к исходному фрейму данных.

library(dplyr)

rp.pptn2 <- rp.pptn %>%
  mutate_at(vars(3:11), funs(. %in% c(1, 2, 6))) %>%
  transmute(pptnlow = rowSums(.[, 3:11])) %>%
  bind_cols(rp.pptn, .)
0 голосов
/ 24 ноября 2018

Один вариант будет reduce с map

library(tidyverse)
map(c(1, 2, 6), ~ rp.pptn %>% 
                   transmute_at(3:11, funs(. == .x)) %>% 
                   reduce(`+`)) %>% 
                   reduce(`+`) %>%
     mutate(rp.pptn, pptnlow = .)

Или с rowSums и map

map(c(1, 2, 6), ~ 
        rp.pptn %>% 
          select(3:11) %>% 
          transmute(pptnlow = rowSums(. == .x)))  %>% 
      bind_cols %>% 
      rowSums %>% 
      mutate(rp.pptn, pptnlow = .)
...