Tengo un montón de columnas en un marco de datos que quiero pegar juntas (separadas por "-") de la siguiente manera:
data <- data.frame('a' = 1:3,
'b' = c('a','b','c'),
'c' = c('d', 'e', 'f'),
'd' = c('g', 'h', 'i'))
i.e.
a b c d
1 a d g
2 b e h
3 c f i
En el que quiero convertirme:
a x
1 a-d-g
2 b-e-h
3 c-f-i
Normalmente podría hacer esto con:
within(data, x <- paste(b,c,d,sep='-'))
y luego eliminar las columnas antiguas, pero desafortunadamente no sé los nombres de las columnas específicamente, solo un nombre colectivo para todas las columnas, por ejemplo, sabría que cols <- c('b','c','d')
¿Alguien sabe una forma de hacer esto?

do.call?evil(parse(...)), por ejemplo , pero creo quedo.calles la llamada correcta aquí.collapse = "-"? apaste?Como una variante de la respuesta de baptiste , con
datadefinido como tiene y las columnas que desea juntar definidas encolsPuede agregar la nueva columna
datay eliminar las antiguas conlo que da
fuente
data.framevector con un solo carácter será una indexación de columna, a pesar de que el primer argumento suele ser el índice de fila.Con el
tidyrpaquete, esto se puede manejar fácilmente en 1 llamada de función.Editar: excluir la primera columna, todo lo demás se pega.
fuente
within(data, x <- paste(b,c,d,sep='-'))como lo ilustraron.unite_(data, "b_c_d", cols)que, o dependiendo de su data.frame real, tambiénunite(data, b_c_d, -a)podría ser un candidato.Construiría un nuevo data.frame:
fuente
d[ , cols]usted, es posible que desee utilizard[ , names(d) != 'a']si todos menos laacolumna se van a pegar juntos.cbind(a = d['a'], x = do.call(paste, c(d[cols], sep = '-'))), por ejemplo, evitar las comas,listydata.framemientras usa eldata.framemétodo decbindSolo para agregar una solución adicional con la
Reduceque probablemente sea más lentado.callpero probadamente mejor queapplyporque evitará lamatrixconversión. Además, en su lugar, unforbucle que podríamos usarsetdiffpara eliminar columnas no deseadasAlternativamente, podríamos actualizar
dataen su lugar usando eldata.tablepaquete (asumiendo datos nuevos)Otra opción es usar en
.SDcolslugar demgetcomo enfuente
Comparé las respuestas de Anthony Damico, Brian Diggs y data_steve en una pequeña muestra
tbl_dfy obtuve los siguientes resultados.Sin embargo, cuando evalué por mi cuenta
tbl_dfcon ~ 1 millón de filas y 10 columnas, los resultados fueron bastante diferentes.fuente
En mi opinión, la
sprintffunción-merece un lugar entre estas respuestas también. Puede usarlo de lasprintfsiguiente manera:lo que da:
Y para crear el marco de datos requerido:
dando:
Aunque
sprintfno tiene una clara ventaja sobre la combinacióndo.call/pastede @BrianDiggs, es especialmente útil cuando también desea rellenar ciertas partes de la cadena deseada o cuando desea especificar el número de dígitos. Consulte?sprintflas diversas opciones.Otra variante sería utilizar
pmapderonroneo:Nota: esta
pmapsolución solo funciona cuando las columnas no son factores.Un punto de referencia en un conjunto de datos más grande:
resulta en:
Datos usados:
fuente
Aquí hay un enfoque bastante poco convencional (pero rápido): use
fwritefromdata.tablepara "pegar" las columnas juntas yfreadvolver a leerlas. Por conveniencia, escribí los pasos como una función llamadafpaste:He aquí un ejemplo:
¿Cómo funciona?
fuente
TMPDIR=/dev/shm R) pero no noto una gran diferencia en comparación con estos resultados. Tampoco he jugado en absoluto con la cantidad de hilos utilizados parafreadofwritepara ver cómo afecta los resultados.fuente
Sé que esta es una pregunta antigua, pero pensé que de todos modos debería presentar la solución simple usando la función paste () como lo sugirió el interlocutor:
fuente