Come distribuire colonne con identificatori duplicati?

A ha il seguente tibble:

structure(list(age = c("21", "17", "32", "29", "15"), gender = structure(c(2L, 1L, 1L, 2L, 2L), .Label = c("Female", "Male"), class = "factor")), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"), .Names = c("age", "gender")) age gender   1 21 Male 2 17 Female 3 32 Female 4 29 Male 5 15 Male 

E sto cercando di usare tidyr::spread per ottenere questo:

  Female Male 1 NA 21 2 17 NA 3 32 NA 4 NA 29 5 NA 15 

Ho pensato che la spread(gender, age) avrebbe funzionato, ma ho ricevuto un messaggio di errore che diceva:

 Error: Duplicate identifiers for rows (2, 3), (1, 4, 5) 

In questo momento hai due valori di age per Female e tre per Male , e non ci sono altre variabili che impediscano che vengano compressi in una singola riga, poiché spread tenta di fare con valori con valori di indice simili / senza:

 library(tidyverse) df <- data_frame(x = c('a', 'b'), y = 1:2) df # 2 rows... #> # A tibble: 2 x 2 #> xy #>   #> 1 a 1 #> 2 b 2 df %>% spread(x, y) # ...become one if there's only one value for each. #> # A tibble: 1 x 2 #> ab #> *   #> 1 1 2 

spread non applica una funzione per combinare più valori (à la dcast ), quindi le righe devono essere indicizzate in modo che ci siano uno o zero valori per una posizione, ad es.

 df <- data_frame(i = c(1, 1, 2, 2, 3, 3), x = c('a', 'b', 'a', 'b', 'a', 'b'), y = 1:6) df # the two rows with each `i` value here... #> # A tibble: 6 x 3 #> ixy #>    #> 1 1 a 1 #> 2 1 b 2 #> 3 2 a 3 #> 4 2 b 4 #> 5 3 a 5 #> 6 3 b 6 df %>% spread(x, y) # ...become one row here. #> # A tibble: 3 x 3 #> iab #> *    #> 1 1 1 2 #> 2 2 3 4 #> 3 3 5 6 

Se i tuoi valori non sono indicizzati in modo naturale dalle altre colonne, puoi aggiungere una colonna di indice univoca (ad esempio aggiungendo i numeri di riga come una colonna) che interromperà la spread dal tentativo di comprimere le righe:

 df <- structure(list(age = c("21", "17", "32", "29", "15"), gender = structure(c(2L, 1L, 1L, 2L, 2L), .Label = c("Female", "Male"), class = "factor")), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"), .Names = c("age", "gender")) df %>% mutate(i = row_number()) %>% spread(gender, age) #> # A tibble: 5 x 3 #> i Female Male #> *    #> 1 1  21 #> 2 2 17  #> 3 3 32  #> 4 4  29 #> 5 5  15 

Se si desidera rimuoverlo in seguito, aggiungere select(-i) . Questo non produce un data.frame terribilmente utile in questo caso, ma può essere molto utile nel bel mezzo di un rimodellamento più complicato.