Convertir la colonne data.frame en vecteur?


164

J'ai un dataframe tel que:

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)

J'ai essayé ce qui suit pour convertir l'une des colonnes en vecteur, mais cela ne fonctionne pas:

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

C'est la seule solution que je pourrais trouver, mais je suppose qu'il doit y avoir une meilleure façon de le faire:

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

Remarque: mon vocabulaire ci-dessus peut être désactivé, veuillez donc me corriger si oui. J'apprends toujours le monde de R. De plus, toute explication de ce qui se passe ici est appréciée (c'est-à-dire se rapportant à Python ou à un autre langage aiderait!)


5
Comme vous le voyez dans les réponses, une lecture attentive de vous ?'[.data.frame'mènera très loin.
joran

Réponses:


208

Je vais essayer d'expliquer cela sans faire d'erreur, mais je parie que cela attirera une clarification ou deux dans les commentaires.

Un bloc de données est une liste. Lorsque vous sous-ensemble un bloc de données en utilisant le nom d'une colonne et [, vous obtenez une sous - liste (ou un sous-bloc de données). Si vous voulez la colonne atomique réelle, vous pouvez utiliser [[, ou quelque peu déroutant (pour moi), vous pouvez faire aframe[,2]qui renvoie un vecteur, pas une sous-liste.

Alors essayez d'exécuter cette séquence et peut-être que les choses seront plus claires:

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

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

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

6
+1 Ceci est utile. Je m'étais habitué à utiliser en aframe[,"a2"]raison de la possibilité de l'utiliser à la fois avec des trames de données et des matrices et semble obtenir les mêmes résultats - un vecteur.
Iterator

8
[..., drop = F]retournera toujours une trame de données
hadley

1
Ceci est particulièrement bon à savoir car la df$xsyntaxe renvoie un vecteur. J'ai utilisé cette syntaxe pendant longtemps, mais quand je devais commencer à utiliser df['name']ou df[n]à récupérer des colonnes, je rencontrais des problèmes lorsque j'essayais de les envoyer à des fonctions qui attendaient des vecteurs. Utiliser df[[n]]ou df[['x']]effacer les choses immédiatement.
rensa

8
Pourquoi as.vectorsemble - t-il silencieusement n'avoir aucun effet? Cela ne devrait-il pas renvoyer un vecteur ou échouer visiblement?
bli

aframe[['a2']]est très utile avec les sfobjets car aframe[,"a2"]renvoie deux colonnes car la colonne de géométrie est incluse.
Matt

41

Il existe maintenant un moyen simple de le faire en utilisant dplyr.

dplyr::pull(aframe, a2)

32

Vous pouvez utiliser l' $extraction:

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

ou la double équerre:

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

21

Vous n'avez pas besoin as.vector(), mais vous avez besoin d'une indexation correcte:avector <- aframe[ , "a2"]

L'autre chose à savoir est la drop=FALSEpossibilité de [:

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: Le rappel de drop=FALSEest utile - cela m'aide dans les cas où je peux sélectionner N colonnes à partir d'un data.frame, dans les cas où N = 1.
Iterator

J'utilise ceci lorsque je ne peux pas prévoir le nombre de colonnes sélectionnées et au cas où une colonne apparaît, le résultat est toujours passé en tant que data.frame avec n colonnes. Un vecteur peut jeter une clé à molette dans les fonctions en bas de la ligne.
Roman Luštrik

11

Un autre avantage de l'utilisation de l'opérateur '[[' est qu'il fonctionne à la fois avec data.frame et data.table. Donc, si la fonction doit être exécutée à la fois pour data.frame et data.table, et que vous souhaitez en extraire une colonne en tant que vecteur, alors

data[["column_name"]] 

est le meilleur.


8

Vous pouvez essayer quelque chose comme ça-

as.vector(unlist(aframe$a2))

C'est bien si vous souhaitez comparer deux colonnes en utilisant identical.
p-robot

5

Si vous utilisez simplement l'opérateur d'extraction, cela fonctionnera. Par défaut, [] définit l'option drop=TRUE, ce que vous voulez ici. Voir ?'['pour plus de détails.

>  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

J'utilise des listes pour filtrer les dataframes selon qu'elles ont ou non une valeur% dans% a list.

J'avais créé manuellement des listes en exportant un dataframe à 1 colonne vers Excel où j'ajouterais "", autour de chaque élément, avant de coller dans R: list <- c ("el1", "el2", ...) qui était généralement suivi de FilteredData <- subset (Data, Column% in% list).

Après avoir recherché stackoverflow et ne pas avoir trouvé de moyen intuitif de convertir un dataframe à 1 colonne en liste, je publie maintenant ma toute première contribution 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

Nous pouvons également convertir les colonnes data.frame de manière générique en un simple vecteur. as.vectorn'est pas suffisant car il conserve la classe et la structure data.frame, nous devons donc également extraire le premier (et seul) élément:

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

Toutes les solutions suggérées jusqu'à présent nécessitent des titres de colonne codés en dur. Cela les rend non génériques (imaginez appliquer ceci aux arguments de fonction).

Alternativement, vous pouvez bien sûr lire d'abord les noms de colonnes de la colonne, puis les insérer dans le code des autres solutions.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.