studio - salvare variabili r




Converti colonne data.frame da fattori a caratteri (9)

Ho un frame di dati. Chiamiamolo 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-

Mi piacerebbe concatenare le righe di questo frame di dati (questa sarà un'altra domanda). Ma guarda:

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

Le colonne di Bob sono fattori. Quindi, ad esempio:

> 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)"

Non comincio a capirlo, ma immagino che questi siano indici nei livelli dei fattori delle colonne (della corte del re caractacus) di bob ? Non è quello di cui ho bisogno.

Stranamente riesco a passare le colonne di bob a mano, e lo faccio

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

che funziona bene. E, dopo un po 'di digitazione, posso ottenere un data.frame le cui colonne sono caratteri anziché fattori. Quindi la mia domanda è: come posso farlo automaticamente? Come posso convertire un data.frame con colonne di fattori in un data.frame con colonne di caratteri senza dover passare manualmente attraverso ciascuna colonna?

Domanda bonus: perché l'approccio manuale funziona?


All'inizio del tuo frame di dati includi stringsAsFactors = FALSE per ignorare tutti i fraintendimenti.


Di solito faccio questa funzione a prescindere da tutti i miei progetti. Facile e veloce.

unfactorize <- function(df){
  for(i in which(sapply(df, class) == "factor")) df[[i]] = as.character(df[[i]])
  return(df)
}

Oppure puoi provare a transform :

newbob <- transform(bob, phenotype = as.character(phenotype))

Assicurati di inserire tutti i fattori che desideri convertire in carattere.

Oppure puoi fare qualcosa del genere e uccidere tutti i parassiti con un colpo solo:

newbob_char <- as.data.frame(lapply(bob[sapply(bob, is.factor)], as.character), stringsAsFactors = FALSE)
newbob_rest <- bob[!(sapply(bob, is.factor))]
newbob <- cbind(newbob_char, newbob_rest)

Non è una buona idea spingere i dati in codice come questo, potrei fare la parte sapply separatamente (in realtà, è molto più facile farlo in quel modo), ma ottieni il punto ... Non ho controllato il codice, ' perché non sono a casa, quindi spero che funzioni! =)

Questo approccio, tuttavia, ha uno svantaggio ... è necessario riorganizzare le colonne in seguito, mentre con la transform puoi fare tutto quello che vuoi, ma a costo di "scrittura in codice stile pedone" ...

Quindi là ... =)



Questo funziona per me - ho finalmente trovato una fodera

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

Se si utilizza il pacchetto data.table per le operazioni su data.frame, il problema non è presente.

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

Se si dispone già di colonne di fattori nel set di dati e si desidera convertirle in caratteri, è possibile eseguire quanto segue.

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" 

So che questa risposta è un po 'in ritardo, ma se capisci come sono memorizzati i fattori, puoi evitare di utilizzare le funzioni basate su applica per ottenere ciò. Il che non significa affatto che le soluzioni applicative non funzionino bene.

I fattori sono strutturati come indici numerici legati a un elenco di "livelli". Questo può essere visto se si converte un fattore in numerico. Così:

> fact <- as.factor(c("a","b","a","d")
> fact
[1] a b a d
Levels: a b d

> as.numeric(fact)
[1] 1 2 1 3

I numeri restituiti nell'ultima riga corrispondono ai livelli del fattore.

> levels(fact)
[1] "a" "b" "d"

Si noti che levels() restituisce una matrice di caratteri. Puoi usare questo fatto per convertire facilmente e in modo compatto i fattori in stringhe o numeri come questo:

> fact_character <- levels(fact)[as.numeric(fact)]
> fact_character
[1] "a" "b" "a" "d"

Questo funziona anche con valori numerici, a patto di avvolgere la tua espressione in as.numeric() .

> num_fact <- factor(c(1,2,3,6,5,4))
> num_fact
[1] 1 2 3 6 5 4
Levels: 1 2 3 4 5 6
> num_num <- as.numeric(levels(num_fact)[as.numeric(num_fact)])
> num_num
[1] 1 2 3 6 5 4

Sto seguendo solo su Matt e Dirk. Se si desidera ricreare il frame di dati esistente senza modificare l'opzione globale, è possibile ricrearlo con un'istruzione apply:

bob <- data.frame(lapply(bob, as.character), stringsAsFactors=FALSE)

Questo convertirà tutte le variabili in "carattere" di classe, se si desidera convertire solo i fattori, vedere la soluzione di Marek di seguito .

Come sottolinea @hadley, il seguente è più conciso.

bob[] <- lapply(bob, as.character)

In entrambi i casi, lapply emette un elenco; tuttavia, a causa delle proprietà magiche di R, l'uso di [] nel secondo caso mantiene la classe data.frame dell'oggetto bob , eliminando così la necessità di riconvertire in un data.frame utilizzando as.data.frame con il argomento stringsAsFactors = FALSE .


Aggiornamento: ecco un esempio di qualcosa che non funziona. Pensavo che sarebbe successo, ma penso che l'opzione stringhe'AsFactors funzioni solo su stringhe di caratteri - lascia i fattori da solo.

Prova questo:

bob2 <- data.frame(bob, stringsAsFactors = FALSE)

In generale, ogni volta che si riscontrano problemi con i fattori che dovrebbero essere dei personaggi, ci sono delle stringsAsFactors che si stringsAsFactors qualche luogo per aiutarti (inclusa un'impostazione globale).







dataframe