2016-09-01 2 views
1

Я пытаюсь создать таблицу 4-сторонних непредвиденных ситуаций из своего набора данных. Мой набор данных выглядит следующим образом:Таблицы непредвиденных обстоятельств из столбцов data.frame

a <- c(1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1) 
b <- c(1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1) 
group1 <- sample(letters[25:26], 12, replace = T) 
group2 <- sample(letters[7:10], 12, replace = T) 

df <- data.frame(a, b, group1, group2) 

Я попытался с aggregate функции. Все в порядке при создании 3-полосного непредвиденного стола

aggregate(cbind(a, b) ~ group1, data = df, FUN = table) 
    group1 a.0 a.1 b.0 b.1 
1  y 3 4 3 4 
2  z 2 3 2 3 

Однако при добавлении второй переменной группировки, выход сбивает с толком, и не требуется.

aggregate(. ~ group1 + group2, data = df, FUN = table) 
    group1 group2 a b 
1  y  g 3 3 
2  z  g 1 1 
3  z  h 1 1 
4  y  i 1 1 
5  z  i 1 1 
6  y  j 2, 1 3 
7  z  j 1, 1 1, 1 

Поскольку мой исходный набор данных довольно большой, я был бы признателен за хороший элегантный и автоматический подход, чтобы справиться с этим. T

ответ

1

Непонятно, ожидаемый выход. Может быть, нам нужно melt/dcast

library(data.table) 
dcast(melt(setDT(df), id.var = c("group1", "group2")), 
         group1 + group2 ~variable + value, length) 

Или использовать recast (обертку для melt/dcast от reshape2)

library(reshape2) 
recast(df, measure.var = c("a", "b"), ... ~ variable + value, length) 
# group1 group2 a_0 a_1 b_0 b_1 
#1  y  g 1 4 3 2 
#2  y  h 1 0 1 0 
#3  y  j 1 1 0 2 
#4  z  g 2 0 0 2 
#5  z  i 0 1 0 1 
#6  z  j 0 1 1 0 

ОП-х aggregate дать этот выход

aggregate(. ~ group1 + group2, data = df, FUN = table) 
# group1 group2 a b 
#1  y  g 1, 4 3, 2 
#2  z  g 2 2 
#3  y  h 1 1 
#4  z  i 1 1 
#5  y  j 1, 1 2 
#6  z  j 1 1 

Если мы хотим aggregate, чтобы получить как levels, затем конвертировать в factor с levels определены и сделать table

do.call(data.frame, aggregate(cbind(a, b) ~ group1 + group2, data = df, 
       FUN = function(x) table(factor(x, levels = 0:1)))) 
# group1 group2 a.0 a.1 b.0 b.1 
#1  y  g 1 4 3 2 
#2  z  g 2 0 0 2 
#3  y  h 1 0 1 0 
#4  z  i 0 1 0 1 
#5  y  j 1 1 0 2 
#6  z  j 0 1 1 0 

Если мы хотим, чтобы все комбинации, есть drop = FALSE в dcast

dcast(melt(setDT(df), id.var = c("group1", "group2")), group1 + group2 ~ 
        variable + value, length, drop = FALSE) 

Или в recast

recast(df, measure.var = c("a", "b"), ... ~ variable + value, length, drop = FALSE) 

ПРИМЕЧАНИЕ: Там не было set.seed для sample , поэтому результат, показанный здесь, будет отличаться от выхода OP

+0

Отлично, спасибо за быстрый ответ! Теперь я вижу, что 'aggregate' только не печатает нули, которые меня путают. Хотя 'melt/dcast' и' recast' работают хорошо, есть ли способ сделать 'aggregate', чтобы дать также нули? – Adela

+1

@Adela Обновлено сообщение. – akrun

+0

Отлично, ну последний вопрос. Я заметил, что в 'do.call' нет значений для комбинаций' z-h' и 'y-i' групп (нет ничего удивительного). Можно ли также печатать нулевые значения для них? Или мне нужно положить их сюда вручную? – Adela

1

Может быть немного сложнее, но, возможно, это помогает, как я понял, вы просто хотели считать так что это может помочь:

#Creating data 
a <- c(1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1) 
b <- c(1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1) 
group1 <- sample(letters[25:26], 12, replace = T) 
group2 <- sample(letters[7:10], 12, replace = T) 
df <- data.frame(a, b, group1, group2) 

# Counting variable a and b seperatly in a data frame 
counta <- xtabs(~ group1 + group2 + a, data = df) 
countb <- xtabs(~ group1 + group2 + b, data = df) 
df.a <- data.frame(counta) 
df.b <- data.frame(countb) 

#Now merging the data.frames: 
result.df <- merge(df.a, df.b, by.x= c("group1", "group2"),by.y=c("group1", "group2"), all = TRUE) 

# Result Looks like this: 
result.df 

#   group1 group2 a Freq.x b Freq.y 
# 1  y  g  0  2 0  1 
# 2  y  g  0  2 1  1 
# 3  y  g  1  0 0  1 
# 4  y  g  1  0 1  1 
# 5  y  h  0  1 0  0 
# 6  y  h  0  1 1  1 
# 7  y  h  1  0 0  0 
# 8  y  h  1  0 1  1 
# 9  y  i  0  1 0  2 
# 10  y  i  0  1 1  1 
# 11  y  i  1  2 0  2 
# 12  y  i  1  2 1  1 
# 13  y  j  0  0 0  0 
# 14  y  j  0  0 1  0 
# 15  y  j  1  0 0  0 
# 16  y  j  1  0 1  0 
# 17  z  g  0  0 0  1 
# 18  z  g  0  0 1  0 
# 19  z  g  1  1 0  1 
# 20  z  g  1  1 1  0 
# 21  z  h  0  0 0  1 
# 22  z  h  0  0 1  1 
# 23  z  h  1  2 0  1 
# 24  z  h  1  2 1  1 
# 25  z  i  0  1 0  0 
# 26  z  i  0  1 1  1 
# 27  z  i  1  0 0  0 
# 28  z  i  1  0 1  1 
# 29  z  j  0  0 0  0 
# 30  z  j  0  0 1  2 
# 31  z  j  1  2 0  0 
# 32  z  j  1  2 1  2 
+0

Спасибо!Это мило. Однако, как я уже сказал, мой исходный набор данных довольно большой и имеет много столбцов, поэтому это было бы слишком сложно. Во всяком случае, для моего короткого примера это работает очень хорошо :) – Adela

Смежные вопросы