Ich habe eine Reihe von Spalten in einem Datenrahmen, die ich wie folgt zusammenfügen möchte (getrennt durch "-"):
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
Was ich werden möchte:
a x
1 a-d-g
2 b-e-h
3 c-f-i
Normalerweise könnte ich das machen mit:
within(data, x <- paste(b,c,d,sep='-'))
und dann die alten Spalten entfernen, aber leider kenne ich die Namen der Spalten nicht speziell, nur einen Sammelnamen für alle Spalten, zB würde ich das wissen cols <- c('b','c','d')
Kennt jemand einen Weg, dies zu tun?
do.call
?evil(parse(...))
, aber ich glaube, hierdo.call
ist der richtige Anruf.collapse = "-"
durchgehen? zupaste
?Als Variante der Antwort von baptiste , mit
data
definiert wie Sie haben und die Spalten, die Sie zusammenstellen möchten, definiert incols
Sie können die neue Spalte hinzufügen
data
und die alten mit löschenwas gibt
quelle
data.frame
mit einem einzelnen Zeichenvektor ist eine Spaltenindizierung, obwohl das erste Argument normalerweise der Zeilenindex ist.Mit
tidyr
package kann dies einfach in einem Funktionsaufruf erledigt werden.Bearbeiten: Erste Spalte ausschließen, alles andere wird eingefügt.
quelle
within(data, x <- paste(b,c,d,sep='-'))
wie sie es dargestellt haben.unite_(data, "b_c_d", cols)
, dass oder abhängig von ihren tatsächlichen data.frameunite(data, b_c_d, -a)
auch ein Kandidat sein könnte.Ich würde einen neuen data.frame erstellen:
quelle
d[ , cols]
möglicherweise verwenden möchten,d[ , names(d) != 'a']
wenn alle außer dera
Spalte zusammen eingefügt werden sollen.cbind(a = d['a'], x = do.call(paste, c(d[cols], sep = '-')))
, um beispielsweise die Kommas zu vermeiden,list
unddata.frame
während Sie diedata.frame
Methode voncbind
Nur um eine zusätzliche Lösung hinzuzufügen,
Reduce
die wahrscheinlich langsamer als,do.call
aber wahrscheinlich besser ist, alsapply
weil sie diematrix
Konvertierung vermeidet . Stattdessenfor
könnten wir stattdessen auch eine Schleife verwendensetdiff
, um unerwünschte Spalten zu entfernenAlternativ könnten wir
data
dasdata.table
Paket mithilfe des Pakets aktualisieren (unter der Annahme neuer Daten).Eine andere Option ist die Verwendung
.SDcols
anstelle vonmget
wie inquelle
Ich habe die Antworten von Anthony Damico, Brian Diggs und data_steve an einer kleinen Stichprobe verglichen
tbl_df
und die folgenden Ergebnisse erhalten.Als ich jedoch alleine
tbl_df
mit ~ 1 Million Zeilen und 10 Spalten auswertete, waren die Ergebnisse ganz anders.quelle
Meiner Meinung nach
sprintf
verdient die Funktion auch einen Platz unter diesen Antworten. Sie könnensprintf
wie folgt verwenden:was gibt:
Und um den erforderlichen Datenrahmen zu erstellen:
Geben:
Obwohl
sprintf
dies keinen klaren Vorteil gegenüber derdo.call
/paste
-Kombination von @BrianDiggs hat, ist es besonders nützlich, wenn Sie auch bestimmte Teile der gewünschten Zeichenfolge auffüllen oder die Anzahl der Ziffern angeben möchten. Siehe?sprintf
für die verschiedenen Optionen.Eine andere Variante wäre die Verwendung
pmap
vonpurrr::Hinweis: Diese
pmap
Lösung funktioniert nur, wenn die Spalten keine Faktoren sind.Ein Benchmark für einen größeren Datensatz:
Ergebnisse in:
Verwendete Daten:
quelle
Hier ist ein ziemlich unkonventioneller (aber schneller) Ansatz: Verwenden Sie
fwrite
von,data.table
um die Spalten zusammenzufügen undfread
wieder einzulesen. Der Einfachheit halber habe ich die Schritte als eine Funktion mit dem Namen geschriebenfpaste
:Hier ist ein Beispiel:
Wie funktioniert es?
quelle
TMPDIR=/dev/shm R
), aber ich bemerke keinen großen Unterschied im Vergleich zu diesen Ergebnissen. Ich habe auch überhaupt nicht mit der Anzahl der verwendeten Threads herumgespieltfread
oder umfwrite
zu sehen, wie sich dies auf die Ergebnisse auswirkt.quelle
Ich weiß, dass dies eine alte Frage ist, dachte aber, dass ich die einfache Lösung trotzdem mit der vom Fragesteller vorgeschlagenen Funktion paste () präsentieren sollte:
quelle