2016-10-27 2 views
0

У меня есть кадр данных в длинном формате, который я бы хотел преобразовать в широкий формат. Кадр данных имеет несколько повторяющихся идентификаторов, которые я хотел бы рассматривать как уникальные экземпляры, и представлять их как отдельные строки в широком фрейме данных.Кастинг от длинного до широкоформатного, с каждым повторением, создающим новую строку

Мой вопрос похож на этот:

Forcing unique values before casting (pivoting) in R

Но в приведенном выше вопросе уникальные записи в конечном итоге, как отдельные столбцы. По моему вопросу, я хотел бы, чтобы данные помещались в отдельные строки. Например:

ID1<-c("A","A","A","A","A","B","B","B","B","B","C","C","C","C","C") 

ID2<-c("R","R","R","L","L","R","R","L","L","R","R","L","L","R","R") 

Sp<-c("Bird","Cat","Bird","Bird","Dog","Dog","Dog","Cat","Cat","Bird","Cat","Dog","Bird","Bird","Cat") 

Count<-c(1,2,2,1,2,1,2,3,2,1,2,3,2,1,5) 

DF<-data.frame(ID1,ID2,Sp,Count) 

После того как я бросил свои данные в широком формате, я хотел бы выходные данные, чтобы выглядеть следующим образом:

ID1 ID2 Bird Cat Dog 
A  R  1  2 0 
A  R  2  0 0 # 2 Birds in the A/ R combination so need second row (don't want to add them together) 
A  L  1  0 2 
B  R  1  0 1 
B  R  0  0 2 
B  L  0  3 0 
B  L  0  2 0 
C  R  1  2 0 
C  R  0  5 0 
C  L  2  0 3 

Если нет повторов в уникальной комбинации ID1/ID2 , литье должно работать как обычно. Но если есть повторение, будет создана вторая (или третья или четвертая) строка.

ответ

1

Вы можете создать вспомогательный столбец ID каждой группы ID1, ID2 и Sp, а затем изменить с ID1, ID2 и AUXID в качестве идентификаторов столбцов:

library(dplyr) 
DF = DF %>% group_by(ID1, ID2, Sp) %>% mutate(AUXID = row_number()) %>% as.data.frame() 
reshape(DF, idvar = c("ID1", "ID2", "AUXID"), timevar = "Sp", dir = "wide") 

# ID1 ID2 AUXID Count.Bird Count.Cat Count.Dog 
# 1 A R  1   1   2  NA 
# 3 A R  2   2  NA  NA 
# 4 A L  1   1  NA   2 
# 6 B R  1   1  NA   1 
# 7 B R  2   NA  NA   2 
# 8 B L  1   NA   3  NA 
# 9 B L  2   NA   2  NA 
# 11 C R  1   1   2  NA 
# 12 C L  1   2  NA   3 
# 15 C R  2   NA   5  NA 

Вы можете уронить AUXID колонку и заполнить NA после ,

Вот data.table версия с dcast() которая обеспечивает параметр fill для заполнения значения NA:

library(data.table) 
(dcast(setDT(DF)[, AUXID := 1:.N, .(ID1, ID2, Sp)], 
     ID1 + ID2 + AUXID ~ Sp, value.var = "Count", fill = 0) 
     [, AUXID := NULL][]) 
# ID1 ID2 Bird Cat Dog 
# 1: A L 1 0 2 
# 2: A R 1 2 0 
# 3: A R 2 0 0 
# 4: B L 0 3 0 
# 5: B L 0 2 0 
# 6: B R 1 0 1 
# 7: B R 0 0 2 
# 8: C L 2 0 3 
# 9: C R 1 2 0 
#10: C R 0 5 0 
+2

Для вашего 'dplyr' методы, вместо базы' reshape' вы можете добавить это к концу цепочка dplyr (после загрузки 'reshape2'):' dcast (ID1 + ID2 + AUXID ~ Sp, value.var = "Count", fill = 0)%>% select (-AUXID) ' – eipi10