r dplyr tidyr

Combine mĂșltiples columnas en datos ordenados



dplyr tidyr (3)

Mi conjunto de datos se ve así:

unique.id abx.1 start.1 stop.1 abx.2 start.2 stop.2 abx.3 start.3 stop.3 abx.4 start.4 1 1 Moxi 2014-01-01 2014-01-07 PenG 2014-01-01 2014-01-07 Vanco 2014-01-01 2014-01-07 Moxi 2014-01-01 2 2 Moxi 2014-01-01 2014-01-02 Cipro 2014-01-01 2014-01-02 PenG 2014-01-01 2014-01-02 Vanco 2014-01-01 3 3 Cipro 2014-01-01 2014-01-05 Vanco 2014-01-01 2014-01-05 Cipro 2014-01-01 2014-01-05 Vanco 2014-01-01 4 4 Vanco 2014-01-02 2014-01-03 Cipro 2014-01-02 2014-01-03 Cipro 2014-01-02 2014-01-03 PenG 2014-01-02 5 5 Vanco 2014-01-01 2014-01-02 PenG 2014-01-01 2014-01-02 PenG 2014-01-01 2014-01-02 Cipro 2014-01-01 stop.4 intervention 1 2014-01-07 0 2 2014-01-02 0 3 2014-01-05 1 4 2014-01-03 1 5 2014-01-02 0

Con algo de código para crear esto:

abxoptions <- c("Cipro", "Moxi", "PenG", "Vanco") df3 <- data.frame( unique.id = 1:5, abx.1 = sample(abxoptions,5, replace=TRUE), start.1 = as.Date(c(''2014-01-01'', ''2014-01-01'', ''2014-01-01'', ''2014-01-02'', ''2014-01-01'')), stop.1 = as.Date(c(''2014-01-07'', ''2014-01-02'', ''2014-01-05'', ''2014-01-03'', ''2014-01-02'')), abx.2 = sample(abxoptions,5, replace=TRUE), start.2 = as.Date(c(''2014-01-01'', ''2014-01-01'', ''2014-01-01'', ''2014-01-02'', ''2014-01-01'')), stop.2 = as.Date(c(''2014-01-07'', ''2014-01-02'', ''2014-01-05'', ''2014-01-03'', ''2014-01-02'')), abx.3 = sample(abxoptions,5, replace=TRUE), start.3 = as.Date(c(''2014-01-01'', ''2014-01-01'', ''2014-01-01'', ''2014-01-02'', ''2014-01-01'')), stop.3 = as.Date(c(''2014-01-07'', ''2014-01-02'', ''2014-01-05'', ''2014-01-03'', ''2014-01-02'')), abx.4 = sample(abxoptions,5, replace=TRUE), start.4 = as.Date(c(''2014-01-01'', ''2014-01-01'', ''2014-01-01'', ''2014-01-02'', ''2014-01-01'')), stop.4 = as.Date(c(''2014-01-07'', ''2014-01-02'', ''2014-01-05'', ''2014-01-03'', ''2014-01-02'')), intervention = c(0,0,1,1,0)

)

Me gustaría ordenar estos datos para que se vean así:

unique.id abx start stop intervention 1 Moxi 2014-01-10 2014-01-07 0 1 Pen G 2014-01-01 2014-01-07 0 1 Vanco 2014-01-01 2014-01-07 0 1 Moxi 2014-01-01 2014-01-07 0 etc etc

Las siguientes soluciones no me llevaron a donde lo necesitaba: reunir múltiples conjuntos de columnas y combinar múltiples columnas en una

Sospecho que el increíble tidyr pakcage de Hadley es el camino a seguir ... simplemente no puedo entender esto. Cualquier ayuda sería muy apreciada.


Casi todos los problemas de ordenamiento de datos se pueden resolver en tres pasos:

  1. Reúna todas las columnas no variables
  2. Separe la columna "colname" en múltiples variables
  3. Re-difundir los datos

(a menudo solo necesitará uno o dos de estos, pero creo que casi siempre están en este orden).

Para sus datos:

  1. La única columna que ya es una variable es unique.id
  2. Debe dividir los nombres de columna actuales en variable y número
  3. Luego debe volver a colocar la variable "variable" en columnas

Esto se ve así:

library(tidyr) library(dplyr) df3 %>% gather(col, value, -unique.id, -intervention) %>% separate(col, c("variable", "number")) %>% spread(variable, value, convert = TRUE) %>% mutate(start = as.Date(start, "1970-01-01"), stop = as.Date(stop, "1970-01-01"))

Su caso es un poco más complicado porque tiene dos tipos de variables, por lo que debe restaurar los tipos al final.


Podrías intentar reshape desde la base R

reshape(df3, direction=''long'', varying=2:ncol(df3), sep=".")

O use merged.stack de splitstackshape

library(splitstackshape) merged.stack(df3, var.stubs=c(''abx'', ''start'', ''stop''), sep=''.'')[, c(''start'', ''stop'') := lapply(.SD, as.Date, origin=''1970-01-01''), .SDcols=4:5][]


Recientemente, se ha agregado una nueva característica a melt.data.table , que permite fundir en múltiples columnas sin problemas. Todo lo que tiene que hacer es proporcionar las columnas que desea fusionar por separado en una list en el argumento measure.vars .

Puede obtener la versión de desarrollo siguiendo estas instrucciones .

require(data.table) ## v1.9.5 setDT(dat) # dat is now a data.table melt(dat, id = 1L, measure = patterns("^abx", "^start", "^stop"), value.name = c("abx", "start", "stop")) # unique.id variable abx start stop # 1: 1 1 Moxi 2014-01-01 2014-01-07 # 2: 2 1 Moxi 2014-01-01 2014-01-02 # 3: 3 1 Cipro 2014-01-01 2014-01-05 # 4: 4 1 Vanco 2014-01-02 2014-01-03 # 5: 5 1 Vanco 2014-01-01 2014-01-02 # 6: 1 2 PenG 2014-01-01 2014-01-07 # 7: 2 2 Cipro 2014-01-01 2014-01-02 # 8: 3 2 Vanco 2014-01-01 2014-01-05 # 9: 4 2 Cipro 2014-01-02 2014-01-03 # 10: 5 2 PenG 2014-01-01 2014-01-02 # 11: 1 3 Vanco 2014-01-01 2014-01-07 # 12: 2 3 PenG 2014-01-01 2014-01-02 # 13: 3 3 Cipro 2014-01-01 2014-01-05 # 14: 4 3 Cipro 2014-01-02 2014-01-03 # 15: 5 3 PenG 2014-01-01 2014-01-02 # 16: 1 4 Moxi 2014-01-01 2014-01-07 # 17: 2 4 Vanco 2014-01-01 2014-01-02 # 18: 3 4 Vanco 2014-01-01 2014-01-05 # 19: 4 4 PenG 2014-01-02 2014-01-03 # 20: 5 4 Cipro 2014-01-01 2014-01-02

He usado números de columna aquí, pero también puede proporcionar nombres de columna.