J'ai un tas de colonnes dans un dataframe que je veux coller ensemble (séparés par "-") comme suit:
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
Ce que je veux devenir:
a x
1 a-d-g
2 b-e-h
3 c-f-i
Je pourrais normalement le faire avec:
within(data, x <- paste(b,c,d,sep='-'))
puis en supprimant les anciennes colonnes, mais malheureusement je ne connais pas spécifiquement les noms des colonnes, seulement un nom collectif pour toutes les colonnes, par exemple je saurais que cols <- c('b','c','d')
Quelqu'un connaît-il un moyen de faire cela?
do.call
?evil(parse(...))
, mais je crois quedo.call
c'est le bon appel ici.collapse = "-"
travers? àpaste
?En variante de la réponse de baptiste , avec
data
défini comme vous l'avez et les colonnes que vous voulez rassembler définies danscols
Vous pouvez ajouter la nouvelle colonne
data
et supprimer les anciennes avecqui donne
la source
data.frame
avec un vecteur de caractère unique sera une indexation de colonne, bien que le premier argument soit généralement l'index de ligne.En utilisant
tidyr
package, cela peut être facilement géré en 1 appel de fonction.Edit: excluez la première colonne, tout le reste est collé.
la source
within(data, x <- paste(b,c,d,sep='-'))
comme ils l'ont illustré.unite_(data, "b_c_d", cols)
que, ou en fonction de leur data.frame réel,unite(data, b_c_d, -a)
pourrait également être un candidat.Je construirais un nouveau data.frame:
la source
d[ , cols]
vous pouvez utiliserd[ , names(d) != 'a']
si tout sauf laa
colonne doit être collé ensemble.cbind(a = d['a'], x = do.call(paste, c(d[cols], sep = '-')))
, par exemple éviter les virgules,list
etdata.frame
en utilisant ladata.frame
méthode decbind
Juste pour ajouter une solution supplémentaire avec
Reduce
qui est probablement plus lente quedo.call
mais mieux meilleure queapply
parce qu'elle évitera lamatrix
conversion. En outre, à la place, unefor
boucle que nous pourrions simplement utilisersetdiff
pour supprimer les colonnes indésirablesSinon, nous pourrions mettre
data
à jour sur place en utilisant ledata.table
package (en supposant des données fraîches)Une autre option consiste à utiliser au
.SDcols
lieu demget
comme dansla source
J'ai comparé les réponses d'Anthony Damico, Brian Diggs et data_steve sur un petit échantillon
tbl_df
et j'ai obtenu les résultats suivants.Cependant, lorsque j'ai évalué moi-même
tbl_df
avec ~ 1 million de lignes et 10 colonnes, les résultats étaient assez différents.la source
A mon avis, la
sprintf
fonction mérite également une place parmi ces réponses. Vous pouvez utilisersprintf
comme suit:qui donne:
Et pour créer le dataframe requis:
donnant:
Bien qu'elle
sprintf
n'ait pas un avantage clair sur la combinaisondo.call
/paste
de @BrianDiggs, elle est particulièrement utile lorsque vous souhaitez également remplir certaines parties de la chaîne souhaitée ou lorsque vous souhaitez spécifier le nombre de chiffres. Voir?sprintf
les différentes options.Une autre variante serait d'utiliser
pmap
deronronnement:Remarque: cette
pmap
solution ne fonctionne que lorsque les colonnes ne sont pas des facteurs.Un benchmark sur un ensemble de données plus large:
résulte en:
Données utilisées:
la source
Voici une approche assez peu conventionnelle (mais rapide): utilisez
fwrite
fromdata.table
to "coller" les colonnes ensemble, etfread
pour les relire. Pour plus de commodité, j'ai écrit les étapes sous forme de fonction appeléefpaste
:Voici un exemple:
Comment ça marche?
la source
TMPDIR=/dev/shm R
) mais je ne remarque pas une énorme différence par rapport à ces résultats. Je n'ai pas non plus joué du tout avec le nombre de threads utilisés pourfread
oufwrite
pour voir comment cela affecte les résultats.la source
Je sais que c'est une vieille question, mais j'ai pensé que je devrais de toute façon présenter la solution simple en utilisant la fonction paste () comme suggéré par l'interrogateur:
la source