Kombinieren Sie zwei oder mehr Spalten in einem Datenrahmen zu einer neuen Spalte mit einem neuen Namen


104

Zum Beispiel, wenn ich das habe:

n = c(2, 3, 5) 
s = c("aa", "bb", "cc") 
b = c(TRUE, FALSE, TRUE) 
df = data.frame(n, s, b)

  n  s     b
1 2 aa  TRUE
2 3 bb FALSE
3 5 cc  TRUE

Dann , wie kombiniere ich die beiden Spalten nund sin eine neue Spalte mit dem Namen , xso dass es wie folgt aussieht:

  n  s     b     x
1 2 aa  TRUE  2 aa
2 3 bb FALSE  3 bb
3 5 cc  TRUE  5 cc

Antworten:


126

Verwenden Sie paste.

 df$x <- paste(df$n,df$s)
 df
#   n  s     b    x
# 1 2 aa  TRUE 2 aa
# 2 3 bb FALSE 3 bb
# 3 5 cc  TRUE 5 cc

. @ thelatemail - Wie füge ich ein Sonderzeichen zwischen Datenpunkten hinzu paste()? Für das obige Beispiel xsollte die Spalte Daten wie 2-aa, dann 3-bbund enthalten 5-cc.
Chetan Arvind Patil

8
. @ thelatemail - Das hat bei mir funktioniert:paste(df$n,df$s,sep="-")
Chetan Arvind Patil

2
Wie können Sie NA weglassen, wenn die Spalte seinen NA-Wert hat? (Ich möchte nicht sehen, 3 NAob df$s[2]=NA)
Cina

34

Zum Einfügen eines Trennzeichens:

df$x <- paste(df$n, "-", df$s)

1
. @ LittleBee - Dies fügt ein Leerzeichen zwischen zwei Daten hinzu. Die endgültige Ausgabe lautet beispielsweise wie folgt: A - Bstatt A-B. Ist es möglich, diesen zusätzlichen Platz zu entfernen?
Chetan Arvind Patil

8
. @ LittleBee - Das hat bei mir funktioniert:paste(df$n,df$s,sep="-")
Chetan Arvind Patil

5
Verwenden Sie paste0 anstelle von paste
Ferroao

3
Dies gibt nicht die gewünschte Ausgabe: OP fragt nach einem Leerzeichen zwischen den Elementen, nicht nach einem weiteren Trennzeichen (was übrigens besser als sepArgument verwendet werden sollte ...). Die andere Antwort, die fast 4 Jahre vor Ihrer veröffentlicht wurde, beantwortet die Frage jedoch perfekt.
Cath

15

Wie bereits in den Kommentaren von Uwe und UseR erwähnt, besteht eine allgemeine Lösung im tidyverseFormat darin, den folgenden Befehl zu verwenden unite:

library(tidyverse)

n = c(2, 3, 5) 
s = c("aa", "bb", "cc") 
b = c(TRUE, FALSE, TRUE) 

df = data.frame(n, s, b) %>% 
  unite(x, c(n, s), sep = " ", remove = FALSE)

1
Was ist x in diesem Beispiel?
Levi

13

Einige Beispiele mit NAs und deren Entfernung mit gelten

n = c(2, NA, NA) 
s = c("aa", "bb", NA) 
b = c(TRUE, FALSE, NA) 
c = c(2, 3, 5) 
d = c("aa", NA, "cc") 
e = c(TRUE, NA, TRUE) 
df = data.frame(n, s, b, c, d, e)

paste_noNA <- function(x,sep=", ") {
gsub(", " ,sep, toString(x[!is.na(x) & x!="" & x!="NA"] ) ) }

sep=" "
df$x <- apply( df[ , c(1:6) ] , 1 , paste_noNA , sep=sep)
df

2
Wenn Sie das tidyrPaket verwenden möchten, um die erwartete Antwort auf die ursprüngliche Frage zu reproduzieren, ist dies ein Einzeiler : tidyr::unite(df, x, n, s, sep = " ", remove = FALSE)[, c(names(df), "x")]. Ich sehe jedoch keinen Grund dafür, da dies df$x <- paste(df$n,df$s)viel einfacher ist.
Uwe

@Ferroao Nun, Antworten sollten auch nicht zu allgemein sein, sonst hätte jede Frage nur eine riesige Antwort, die alles beinhaltet. Das Entfernen von NAs war nicht Teil der einfachen Frage von OP, daher sehe ich nicht, wie diese zusätzliche Komplexität einem einfachen pasteoder einen Mehrwert verleiht tidyr::unite.
avid_useR

@Ferroao Danke, du hast mein Leben gerettet. Bitte verschieben Sie die Funktion paste_noNA vor df $ x <-apply.
Malajisi

11

Verwenden von dplyr::mutate:

library(dplyr)
df <- mutate(df, x = paste(n, s)) 

df 
> df
  n  s     b    x
1 2 aa  TRUE 2 aa
2 3 bb FALSE 3 bb
3 5 cc  TRUE 5 cc

1
Nein, wie bereits vorhandene Antworten verwenden Sie Einfügen , nicht Mutieren .
zx8754

Ich dachte, ich würde demonstrieren, wie Spalten als Teil von a kombiniert werden können dplyr::mutate(). Entschuldigung, ich versuche nur, hilfreich zu sein - ich werde die Website nicht mehr verschmutzen und mich zukünftiger Postings enthalten.
Sbha

Entschuldigung, wenn es als unhöflich herauskam. OP das Problem durch die Verwendung nicht gelöst ist mutieren , ist Frage nicht über die Verwendung dplyr , aber wie Spaltenwerte zu kombinieren. Ich weise nur darauf hin, dass sie Paste brauchen , die nicht mutiert . Wenn wir dplyr richtig demonstrieren wollen , verwenden Sie die Funktion unite .
zx8754

9

Wir können paste0 verwenden :

df$combField <- paste0(df$x, df$y)

Wenn Sie nicht möchten, dass im verketteten Feld ein Auffüllbereich eingefügt wird. Dies ist nützlicher, wenn Sie das kombinierte Feld als eindeutige ID verwenden möchten, die Kombinationen aus zwei Feldern darstellt.


6

Anstatt

  • paste (Standard-Leerzeichen),
  • paste0(erzwinge die Aufnahme von fehlenden NAals Zeichen) oder
  • unite (beschränkt auf 2 Spalten und 1 Trennzeichen),

Ich würde eine Alternative vorschlagen, die so flexibel wie, paste0aber vorsichtiger ist mit NA:stringr::str_c

library(tidyverse)

# check the missing value!!
df <- tibble(
  n = c(2, 2, 8),
  s = c("aa", "aa", NA_character_),
  b = c(TRUE, FALSE, TRUE)
)

df %>% 
  mutate(
    paste = paste(n,"-",s,".",b),
    paste0 = paste0(n,"-",s,".",b),
    str_c = str_c(n,"-",s,".",b)
  ) %>% 

  # convert missing value to ""
  mutate(
    s_2=str_replace_na(s,replacement = "")
  ) %>% 
  mutate(
    str_c_2 = str_c(n,"-",s_2,".",b)
  )
#> # A tibble: 3 x 8
#>       n s     b     paste          paste0     str_c      s_2   str_c_2   
#>   <dbl> <chr> <lgl> <chr>          <chr>      <chr>      <chr> <chr>     
#> 1     2 aa    TRUE  2 - aa . TRUE  2-aa.TRUE  2-aa.TRUE  "aa"  2-aa.TRUE 
#> 2     2 aa    FALSE 2 - aa . FALSE 2-aa.FALSE 2-aa.FALSE "aa"  2-aa.FALSE
#> 3     8 <NA>  TRUE  8 - NA . TRUE  8-NA.TRUE  <NA>       ""    8-.TRUE

Erstellt am 2020-04-10 durch das reprex-Paket (v0.3.0)

zusätzlicher Hinweis aus der str_cDokumentation

Wie die meisten anderen R-Funktionen sind fehlende Werte "ansteckend": Wenn ein fehlender Wert mit einer anderen Zeichenfolge kombiniert wird, fehlt immer das Ergebnis. Verwenden Sie str_replace_na()zum Konvertieren NAin"NA"


1
paste0(n,"-",s,".",b)und str_c(n,"-",s,".",b)sind genau gleich, beide verwenden ein Standardtrennzeichen, das die leere Zeichenfolge ist ''. Ich weiß auch nicht, warum paste"aufgeräumt" ist, du meinst, du magst keine Räume?
Axeman

paste0und str_csind nicht genau das gleiche. Schauen Sie sich diese Links an: (1) rdocumentation.org/packages/stringr/versions/1.3.1/topics/str_c (2) stackoverflow.com/questions/53118271/…
avallecam

Ah ich sehe! Vielen Dank! Wie unterschiedlich sie sind, wäre eine gute Ergänzung zu dieser Antwort (und die str_cDokumentation könnte auch expliziter sein!).
Axeman

@ Axeman danke für deinen Vorschlag. Ich habe die Antwort vereinfacht und einen zusätzlichen Hinweis zu diesem Thema hinzugefügt
avallecam

2

Es gibt andere gute Antworten, aber wenn Sie die Spaltennamen oder die Anzahl der Spalten, die Sie im Voraus verketten möchten, nicht kennen, ist Folgendes hilfreich.

df = data.frame(x = letters[1:5], y = letters[6:10], z = letters[11:15])
colNames = colnames(df) # could be any number of column names here
df$newColumn = apply(df[, colNames, drop = F], MARGIN = 1, FUN = function(i) paste(i, collapse = ""))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.