Convertire la colonna data.frame in un vettore?


164

Ho un frame di dati come:

a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)

Ho provato quanto segue per convertire una delle colonne in un vettore, ma non funziona:

avector <- as.vector(aframe['a2'])
class(avector) 
[1] "data.frame"

Questa è l'unica soluzione che potrei trovare, ma suppongo che ci debba essere un modo migliore per farlo:

class(aframe['a2']) 
[1] "data.frame"
avector = c()
for(atmp in aframe['a2']) { avector <- atmp }
class(avector)
[1] "numeric"

Nota: il mio vocabolario sopra potrebbe essere disattivato, quindi per favore correggimi in tal caso. Sto ancora imparando il mondo di R. Inoltre, qualsiasi spiegazione di ciò che sta accadendo qui è apprezzata (vale a dire in relazione a Python o qualche altra lingua sarebbe d'aiuto!)


5
Come vedi nelle risposte, una lettura attenta ?'[.data.frame'ti porterà molto lontano.
joran,

Risposte:


208

Proverò a spiegarlo senza fare errori, ma scommetto che ciò attrarrà un chiarimento o due nei commenti.

Un frame di dati è un elenco. Quando si imposta un sottoinsieme di un frame di dati utilizzando il nome di una colonna e [, ciò che si ottiene è un elenco secondario (o un frame di dati secondario). Se si desidera la colonna atomica effettiva, è possibile utilizzare [[, o in modo un po 'confuso (per me), aframe[,2]che restituisce un vettore, non un elenco secondario.

Quindi prova a eseguire questa sequenza e forse le cose saranno più chiare:

avector <- as.vector(aframe['a2'])
class(avector) 

avector <- aframe[['a2']]
class(avector)

avector <- aframe[,2]
class(avector)

6
+1 Questo è utile. Mi ero abituato a usare a aframe[,"a2"]causa della capacità di utilizzare questo con entrambi i frame di dati e le matrici e sembra ottenere gli stessi risultati - un vettore.
Iteratore

8
[..., drop = F]restituirà sempre un frame di dati
Hadley,

1
Ciò è particolarmente utile da sapere perché la df$xsintassi restituisce un vettore. Ho usato questa sintassi per molto tempo, ma quando ho dovuto iniziare a utilizzare df['name']o df[n]recuperare colonne, ho riscontrato problemi quando ho cercato di inviarli a funzioni che prevedevano vettori. Usare df[[n]]o df[['x']]cancellare le cose subito.
rensa,

8
Perché as.vectorsembra che non abbia silenziosamente alcun effetto? Questo non dovrebbe o restituire un vettore o chiaramente fallire?
Bla

aframe[['a2']]è molto utile con gli sfoggetti perché aframe[,"a2"]restituirà due colonne perché la colonna della geometria è inclusa.
Matt,

41

Ora c'è un modo semplice per farlo usando dplyr.

dplyr::pull(aframe, a2)

32

È possibile utilizzare l' $estrazione:

class(aframe$a1)
[1] "numeric"

o la doppia staffa quadrata:

class(aframe[["a1"]])
[1] "numeric"

21

Non hai bisogno as.vector() , ma è necessario l'indicizzazione corretta:avector <- aframe[ , "a2"]

L'altra cosa da tenere presente è la drop=FALSEpossibilità di [:

R> aframe <- data.frame(a1=c1:5, a2=6:10, a3=11:15)
R> aframe
  a1 a2 a3
1  1  6 11
2  2  7 12
3  3  8 13
4  4  9 14
5  5 10 15
R> avector <- aframe[, "a2"]
R> avector
[1]  6  7  8  9 10
R> avector <- aframe[, "a2", drop=FALSE]
R> avector
  a2
1  6
2  7
3  8
4  9
5 10
R> 

4
+1: il promemoria di drop=FALSEè utile - questo mi aiuta nei casi in cui posso selezionare N colonne da un data.frame, in quei casi in cui N = 1.
Iteratore

Lo uso quando non riesco a prevedere il numero di colonne selezionate e nel caso in cui una colonna si presenti, il risultato viene comunque passato come data.frame con n colonne. Un vettore può lanciare una chiave inglese nelle funzioni lungo la linea.
Roman Luštrik,

11

Un altro vantaggio dell'utilizzo dell'operatore '[[' è che funziona sia con data.frame che data.table. Quindi, se la funzione deve essere eseguita sia per data.frame che per data.table e si desidera estrarre una colonna da essa come vettore,

data[["column_name"]] 

è meglio.


8

Puoi provare qualcosa del genere-

as.vector(unlist(aframe$a2))

Questo è utile se si desidera confrontare due colonne usando identical.
p-robot,

5

Se usi semplicemente l'operatore di estrazione funzionerà. Per impostazione predefinita, [] imposta l'opzione drop=TRUE, che è quello che vuoi qui. Vedi ?'['per maggiori dettagli.

>  a1 = c(1, 2, 3, 4, 5)
>  a2 = c(6, 7, 8, 9, 10)
>  a3 = c(11, 12, 13, 14, 15)
>  aframe = data.frame(a1, a2, a3)
> aframe[,'a2']
[1]  6  7  8  9 10
> class(aframe[,'a2'])
[1] "numeric"


3
a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)
avector <- as.vector(aframe['a2'])

avector<-unlist(avector)
#this will return a vector of type "integer"

2

Uso gli elenchi per filtrare i frame di dati in base al loro valore% in% a list.

Avevo creato manualmente elenchi esportando un frame di dati a 1 colonna in Excel dove avrei aggiunto "", attorno a ciascun elemento, prima di incollare in R: list <- c ("el1", "el2", ...) che di solito era seguito da FilteredData <- sottoinsieme (Dati, colonna% nell'elenco%).

Dopo aver cercato StackOverflow e non ho trovato un modo intuitivo per convertire un frame di dati a 1 colonna in un elenco, sto pubblicando il mio primo contributo in assoluto StackOverflow:

# assuming you have a 1 column dataframe called "df"
list <- c()
for(i in 1:nrow(df)){
  list <- append(list, df[i,1])
}
View(list)
# This list is not a dataframe, it is a list of values
# You can filter a dataframe using "subset([Data], [Column] %in% list")

1

Possiamo anche convertire le colonne data.frame genericamente in un semplice vettore. as.vectornon è sufficiente in quanto mantiene la classe e la struttura data.frame, quindi dobbiamo anche estrarre il primo (e unico) elemento:

df_column_object <- aframe[,2]
simple_column <- df_column_object[[1]]

Tutte le soluzioni suggerite finora richiedono titoli di colonne hardcoding. Questo li rende non generici (immagina di applicarlo agli argomenti della funzione).

In alternativa, puoi ovviamente leggere prima i nomi delle colonne dalla colonna e poi inserirli nel codice nelle altre soluzioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.