Как суммировать повторяющиеся значения в соответствии с уровнем в столбце и выводить таблицу значений? - PullRequest
0 голосов
/ 04 июня 2018

Я новичок в R, и у меня есть данные, которые выглядят примерно так:

categories <- c("A","B","C","A","A","B","C","A","B","C","A","B","B","C","C")
animals <- c("cat","cat","cat","dog","mouse","mouse","rabbit","rat","shark","shark","tiger","tiger","whale","whale","worm")
dat <- cbind(categories,animals)

Некоторые животные повторяются в соответствии с категорией.Например, «кошка» появляется во всех трех категориях A, B и C.

Мне нравится, что мой новый вывод данных с фрейма выглядит примерно так:

A   B   C   count
1   1   1   1
1   1   0   2
1   0   1   0
0   1   1   2
1   0   0   2
0   1   0   0
0   0   1   2
0   0   0   0

Число 1 под A, B и C означает, что животное появляется в этой категории, 0 означает, что животное не появляется в этой категории.Например, первая строка имеет 1 во всех трех категориях.Количество для первой строки равно 1, потому что «кошка» - единственное животное, которое повторяется в каждой категории.

Есть ли в R функция, которая поможет мне достичь этого?Заранее спасибо.

Ответы [ 4 ]

0 голосов
/ 05 июня 2018

Добавление решения data.table.Во-первых, поверните животных против категорий, используя данные.Затем создайте комбинации A, B, C, используя CJ.Объедините эти комбинации с помощью dat и посчитайте количество вхождений для каждой комбинации.

dcast(as.data.table(dat), animals ~ categories, length)[
    CJ(A=0:1, B=0:1, C=0:1), .(count=.N), on=c("A","B","C"), by=.EACHI]
0 голосов
/ 04 июня 2018

Мы можем использовать table, чтобы создать кросс-табуляцию categories и animals, транспонировать, преобразовать в data.frame, group_by all categories и подсчитать частоту для каждой комбинации:

library(dplyr)
library(tidyr)

as.data.frame.matrix(t(table(dat))) %>%
  group_by_all() %>%
  summarize(Count = n())

Результат:

# A tibble: 5 x 4
# Groups:   A, B [?]
      A     B     C Count
  <int> <int> <int> <int>
1     0     0     1     2
2     0     1     1     2
3     1     0     0     2
4     1     1     0     2
5     1     1     1     1

Редактировать (спасибо @C. Braun).Вот как можно также включить нулевые комбинации A, B, C:

as.data.frame.matrix(t(table(dat))) %>%
  bind_rows(expand.grid(A = c(0,1), B = c(0,1), C = c(0,1))) %>%
  group_by_all() %>%
  summarize(Count = n()-1) 

или с complete, как предложено @Ryan:

as.data.frame.matrix(t(table(dat))) %>%
  mutate(non_missing = 1) %>%
  complete(A, B, C) %>%
  group_by(A, B, C) %>%
  summarize(Count = sum(ifelse(is.na(non_missing), 0, 1))) 

Результат:

# A tibble: 8 x 4
# Groups:   A, B [?]
      A     B     C Count
  <dbl> <dbl> <dbl> <dbl>
1     0     0     0     0
2     0     0     1     2
3     0     1     0     0
4     0     1     1     2
5     1     0     0     2
6     1     0     1     0
7     1     1     0     2
8     1     1     1     1
0 голосов
/ 04 июня 2018

У нас есть

xxtabs <- function(df, formula) {
    xt <- xtabs(formula, df)
    xxt <- xtabs( ~ . , as.data.frame.matrix(xt))
    as.data.frame(xxt)
}

и

> xxtabs(dat, ~ animals + categories)
  A B C Freq
1 0 0 0    0
2 1 0 0    2
3 0 1 0    0
4 1 1 0    2
5 0 0 1    2
6 1 0 1    0
7 0 1 1    2
8 1 1 1    1

(dat действительно должно быть построено как data.frame(animals, categories)).Этот базовый подход использует xtabs() для формирования первой кросс-таблицы

xt <- xtabs(~ animals + categories, dat)

, затем принудительно использует as.data.frame.matrix() ко второму data.frame и использует вторую кросс-табуляцию всех столбцов вычисленных данных.frame

xxt <- xtabs(~ ., as.data.frame.matrix(xt))

приведен к нужной форме

as.data.frame(xxt)

Я первоначально сказал, что этот подход был «загадочным», потому что он основан на знании разницы между as.data.frame() и as.data.frame.matrix();Я думаю о xtabs() как о инструменте, который пользователи базы R должны знать.Я вижу, однако, что другие решения также требуют этого тайного знания, а также знания более неясных (например, complete(), group_by_all(), funs()) частей тидиверса.Кроме того, другие ответы не (или, по крайней мере, не написаны так, как это позволяет) легко обобщаются;xxtabs() на самом деле ничего не знает о структуре входящего data.frame, тогда как в других ответах присутствуют неявные знания о поступающих данных.

Один «урок», извлеченный из аккуратного подхода, заключается всначала аргумент данных, позволяющий обвязать

dat %>% xxtabs(~ animals + categories)
0 голосов
/ 04 июня 2018

Если я вас правильно понял, это должно сработать.

require(tidyverse)

 dat %>% 
  mutate(value = 1) %>%
  spread(categories, value) %>%
  mutate_if(is.numeric, funs(replace(., is.na(.), 0))) %>% 
  mutate(count = rowSums(data.frame(A, B, C), na.rm = TRUE)) %>%
  group_by(A, B, C) %>%
  summarize(Count = n()) 

# A tibble: 5 x 4
# Groups:   A, B [?]
      A     B     C Count
  <dbl> <dbl> <dbl> <int>
1    0.    0.    1.     2
2    0.    1.    1.     2
3    1.    0.    0.     2
4    1.    1.    0.     2
5    1.    1.    1.     1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...