2014-01-06 2 views
2

Я хотел бы обобщить или заполнить таблицы без сброса пустых уровней. Интересно, есть ли у кого-нибудь идеи по этому поводу?Резюме/Совокупность в R без уровней снижения

В качестве примера, Вот кадр данных

df1<-data.frame(Method=c(rep("A",3),rep("B",2),rep("C",4)), 
     Type=c("Fast","Fast","Medium","Fast","Slow","Fast","Medium","Slow","Slow"), 
      Measure=c(1,1,2,1,3,1,1,2,2)) 

Два подхода с использованием базы и doBy пакет.

#base 
aggregate(Measure~Method+Type,data=df1,FUN=length) 

require(doBy) 
summaryBy(Measure~Method+Type,data=df1,FUN=length) 

Они оба дают те же результаты, отсортированные по-разному, но проблема в том, что я хотел бы все комбинации метода и типа и отсутствуют меры, вставленные в качестве ВПЛ. Или все уровни обоих моих факторов должны поддерживаться.

df1$Type 
df1$Method 

Может plyr есть что-то, но я не знаю, как это работает.

+1

См. [Аналогичный вопрос с data.table] (http://stackoverflow.com/questions/20914284/including-all-permutations-when-using-data-table-by) – BrodieG

+3

Также см. 'Ddply', и это' .drop'. – joran

+2

Как уже сказал @joran, но поскольку вы не знакомы с plyr: 'ddply (df1,. (Method, Type), суммировать, Measure = length (Measure), .drop = F)' –

ответ

0

Спасибо за ваши ответы. Я думаю, что все они работают, чтобы дать результат. Но комментарий Марк Heckmann с этим кодом

ddply(df1, .(Method, Type), summarise, Measure=length(Measure), .drop=F)

, кажется, дает хороший чистый выход dataframe с хорошим заголовком и с минимальным кодом. С другой стороны, он нуждается в дополнительном пакете.

4

Посмотрите tapply:

with(df1, tapply(Measure, list(Method, Type), FUN = length)) 

# Fast Medium Slow 
# A 2  1 NA 
# B 1  NA 1 
# C 1  1 2 
1

В базовой R, by будет возвращать результат для отсутствующих значений.

result <- by(df1, INDICES=list(df1$Method, df1$Type), FUN=nrow) 
cbind(expand.grid(attributes(result)$dimnames), as.vector(result)) 

# Var1 Var2 as.vector(result) 
# 1 A Fast     2 
# 2 B Fast     1 
# 3 C Fast     1 
# 4 A Medium     1 
# 5 B Medium    NA 
# 6 C Medium     1 
# 7 A Slow    NA 
# 8 B Slow     1 
# 9 C Slow     2 
1

Вы можете попробовать by() в базе R. Например,

tab <- with(df1, by(df1, list(Method = Method, Type = Type), FUN = length)) 
Method: A 
Type: Fast 
[1] 2 
------------------------------------------------------------  
Method: B 
Type: Fast 
[1] 1 
------------------------------------------------------------  
Method: C 
Type: Fast 
[1] 1 
------------------------------------------------------------  
Method: A 
Type: Medium 
[1] 1 
------------------------------------------------------------  
Method: B 
Type: Medium 
[1] NA 
------------------------------------------------------------  
Method: C 
Type: Medium 
[1] 1 
------------------------------------------------------------  
Method: A 
Type: Slow 
[1] NA 
------------------------------------------------------------  
.... 

Обратите внимание, что это только print() метод делая его сложным. Если мы unclass()tab, мы видим, что это просто многоходовой таблица в данном случае:

R> unclass(tab) 
     Type 
Method Fast Medium Slow 
    A 2  1 NA 
    B 1  NA 1 
    C 1  1 2 
attr(,"call") 
by.data.frame(data = df1, INDICES = list(Method = Method, Type = Type), 
    FUN = nrow) 

и вы можете работать с этим, как это просто массив (матрица). И если вы предпочитаете это в длинном формате, вы можете легко развернуть его:

nr <- nrow(tab) 
ltab <- cbind.data.frame(Method = rep(rownames(tab), times = nr), 
         Type = rep(colnames(tab), each = nr), 
         Count = c(tab)) 
ltab 

R> ltab 
    Method Type Count 
1  A Fast  2 
2  B Fast  1 
3  C Fast  1 
4  A Medium  1 
5  B Medium NA 
6  C Medium  1 
7  A Slow NA 
8  B Slow  1 
9  C Slow  2 
+1

не nitpick, но вы возвращаете количество столбцов для каждой группы, а не количество наблюдений. –

+0

@MatthewPlourde Спасибо, Мэтью, просто появляется, чтобы показать, что я не должен отвечать на вопросы здесь и на твиттере и делать все в одно и то же время ...! –

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