395 Stimmen

data.frame-Spalten von Faktoren in Zeichen umwandeln

Ich habe einen Datenrahmen. Nennen wir ihn bob :

> head(bob)
                 phenotype                         exclusion
GSM399350 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399351 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399352 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399353 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399354 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399355 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-

Ich möchte die Zeilen dieses Datenrahmens verketten (dies wird eine weitere Frage sein). Aber sehen Sie:

> class(bob$phenotype)
[1] "factor"

Bob Spalten sind Faktoren. Also, zum Beispiel

> as.character(head(bob))
[1] "c(3, 3, 3, 6, 6, 6)"       "c(3, 3, 3, 3, 3, 3)"      
[3] "c(29, 29, 29, 30, 30, 30)"

Ich verstehe das nicht ganz, aber ich vermute, dass es sich um Indizes für die Ebenen der Faktoren der Säulen (des Hofes von König Caractacus) von bob ? Nicht das, was ich brauche.

Seltsamerweise kann ich durch die Spalten von bob von Hand, und tun

bob$phenotype <- as.character(bob$phenotype)

was gut funktioniert. Und nach einiger Tipparbeit kann ich einen data.frame erhalten, dessen Spalten Zeichen und nicht Faktoren sind. Meine Frage lautet also: Wie kann ich dies automatisch tun? Wie kann ich einen data.frame mit Faktorenspalten in einen data.frame mit Zeichenspalten umwandeln, ohne jede Spalte manuell durchgehen zu müssen?

Zusatzfrage: Warum funktioniert der manuelle Ansatz?

6voto

jangorecki Punkte 15157

Wenn Sie Folgendes verwenden würden data.table Paket für die Operationen auf data.frame, dann ist das Problem nicht vorhanden.

library(data.table)
dt = data.table(col1 = c("a","b","c"), col2 = 1:3)
sapply(dt, class)
#       col1        col2 
#"character"   "integer" 

Wenn Sie bereits Faktorspalten in Ihrem Datensatz haben und diese in Zeichen umwandeln möchten, können Sie wie folgt vorgehen.

library(data.table)
dt = data.table(col1 = factor(c("a","b","c")), col2 = 1:3)
sapply(dt, class)
#     col1      col2 
# "factor" "integer" 
upd.cols = sapply(dt, is.factor)
dt[, names(dt)[upd.cols] := lapply(.SD, as.character), .SDcols = upd.cols]
sapply(dt, class)
#       col1        col2 
#"character"   "integer"

3voto

radhikesh93 Punkte 790

Neue Funktion "across" wurde in dplyr eingeführt Version 1.0.0 . Die neue Funktion wird die "scoped" Variablen (_if, _at, _all) ersetzen. Hier ist die offizielle Dokumentation

library(dplyr)
bob <- bob %>% 
       mutate(across(where(is.factor), as.character))

3voto

user1617979 Punkte 2250

Das funktioniert bei mir - ich habe endlich einen One-Liner gefunden

df <- as.data.frame(lapply(df,function (y) if(class(y)=="factor" ) as.character(y) else y),stringsAsFactors=F)

2voto

davsjob Punkte 1712

Sie sollten Folgendes verwenden convert en hablar was eine lesbare Syntax ergibt, die mit tidyverse Rohre:

library(dplyr)
library(hablar)

df <- tibble(a = factor(c(1, 2, 3, 4)),
             b = factor(c(5, 6, 7, 8)))

df %>% convert(chr(a:b))

die Sie erhalten:

  a     b    
  <chr> <chr>
1 1     5    
2 2     6    
3 3     7    
4 4     8

2voto

nexonvantec Punkte 532

Mit dem dplyr -Paket geladen verwenden

bob=bob%>%mutate_at("phenotype", as.character)

wenn Sie nur die phenotype -Spalte speziell.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X