Utilizzo di spread con identificativi duplicati per le righe

Ho un dataframe di forma lunga che ha più voci per la stessa data e persona.

jj <- data.frame(month=rep(1:3,4), student=rep(c("Amy", "Bob"), each=6), A=c(9, 7, 6, 8, 6, 9, 3, 2, 1, 5, 6, 5), B=c(6, 7, 8, 5, 6, 7, 5, 4, 6, 3, 1, 5)) 

Voglio convertirlo in forma ampia e renderlo così:

 month Amy.A Bob.A Amy.B Bob.B 1 2 3 1 2 3 1 2 3 1 2 3 

La mia domanda è molto simile a questo . Ho usato il codice dato nella risposta:

 kk % gather(variable, value, -(month:student)) %>% unite(temp, student, variable) %>% spread(temp, value) 

ma dà il seguente errore:

Errore: identificatori duplicati per righe (1, 4), (2, 5), (3, 6), (13, 16), (14, 17), (15, 18), (7, 10), (8 , 11), (9, 12), (19, 22), (20, 23), (21, 24)

Grazie in anticipo. Nota: non voglio cancellare più voci.

Il problema sono le due colonne per A e B Se riusciamo a creare una colonna con un valore, possiamo diffondere i dati come preferisci. Dai un’occhiata all’output di jj_melt quando usi il codice qui sotto.

 library(reshape2) jj_melt <- melt(jj, id=c("month", "student")) jj_spread <- dcast(jj_melt, month ~ student + variable, value.var="value", fun=sum) # month Amy_A Amy_B Bob_A Bob_B # 1 1 17 11 8 8 # 2 2 13 13 8 5 # 3 3 15 15 6 11 

Non lo contrassegnerò come duplicato poiché l'altra domanda non è stata riassunta per sum , ma la risposta data.table potrebbe aiutare con un argomento aggiuntivo, fun=sum :

 library(data.table) dcast(setDT(jj), month ~ student, value.var=c("A", "B"), fun=sum) # month A_sum_Amy A_sum_Bob B_sum_Amy B_sum_Bob # 1: 1 17 8 11 8 # 2: 2 13 8 13 5 # 3: 3 15 6 15 11 

Se si desidera utilizzare la soluzione di tidyr , combinarla con dcast per riassumere per sum .

 as.data.frame(jj) library(tidyr) jj %>% gather(variable, value, -(month:student)) %>% unite(temp, student, variable) %>% dcast(month ~ temp, fun=sum) # month Amy_A Amy_B Bob_A Bob_B # 1 1 17 11 8 8 # 2 2 13 13 8 5 # 3 3 15 15 6 11 

modificare

In base alle tue nuove esigenze, ho aggiunto una colonna di attività.

 library(dplyr) jj %>% group_by(month, student) %>% mutate(id=1:n()) %>% melt(id=c("month", "id", "student")) %>% dcast(... ~ student + variable, value.var="value") # month id Amy_A Amy_B Bob_A Bob_B # 1 1 1 9 6 3 5 # 2 1 2 8 5 5 3 # 3 2 1 7 7 2 4 # 4 2 2 6 6 6 1 # 5 3 1 6 8 1 6 # 6 3 2 9 7 5 5 

È ansible utilizzare anche le altre soluzioni. Qui ho aggiunto un'espressione opzionale per organizzare l'output finale per numero di attività:

 library(tidyr) jj %>% gather(variable, value, -(month:student)) %>% unite(temp, student, variable) %>% group_by(temp) %>% mutate(id=1:n()) %>% dcast(... ~ temp) %>% arrange(id) # month id Amy_A Amy_B Bob_A Bob_B # 1 1 1 9 6 3 5 # 2 2 2 7 7 2 4 # 3 3 3 6 8 1 6 # 4 1 4 8 5 5 3 # 5 2 5 6 6 6 1 # 6 3 6 9 7 5 5 

La syntax data.table è compatta perché consente più colonne value.var e si prenderà cura dello spread per noi. Possiamo quindi saltare la melt -> cast processo di melt -> cast .

 library(data.table) setDT(jj)[, activityID := rowid(student)] dcast(jj, ... ~ student, value.var=c("A", "B")) # month activityID A_Amy A_Bob B_Amy B_Bob # 1: 1 1 9 3 6 5 # 2: 1 4 8 5 5 3 # 3: 2 2 7 2 7 4 # 4: 2 5 6 6 6 1 # 5: 3 3 6 1 8 6 # 6: 3 6 9 5 7 5 

La tua risposta mancava di identificazione mutata! Ecco la soluzione usando solo dplyr packge.

 jj %>% gather(variable, value, -(month:student)) %>% unite(temp, student, variable) %>% group_by(temp) %>% mutate(id=1:n()) %>% spread(temp, value) # A tibble: 6 x 6 # month id Amy_A Amy_B Bob_A Bob_B # *       # 1 1 1 9 6 3 5 # 2 1 4 8 5 5 3 # 3 2 2 7 7 2 4 # 4 2 5 6 6 6 1 # 5 3 3 6 8 1 6 # 6 3 6 9 7 5 5 
 gather(data, key = "key", value = "value", ..., na.rm = FALSE, convert = FALSE, factor_key = FALSE) 

Controlla se hai invertito la chiave e il valore. “Chiave” è il nome della nuova chiave e “valore” è il valore effettivo.