Convertir une ligne d'un bloc de données en vecteur

116

Je souhaite créer un vecteur à partir d'une ligne d'un bloc de données. Mais je ne veux pas avoir de noms de lignes et de colonnes. J'ai essayé plusieurs choses ... mais je n'ai pas eu de chance.

Voici ma trame de données:

> df <- data.frame(a=c(1,2,4,2),b=c(2,6,2,1),c=c(2.6,8.2,7.5,3))
> df
  a b   c
1 1 2 2.6
2 2 6 8.2
3 4 2 7.5
4 2 1 3.0

J'ai essayé:

> newV <- as.vector(df[1,])
> newV
  a b   c
1 1 2 2.6

Mais je veux vraiment quelque chose qui ressemble à ceci:

> newV <- c( 1,2,2.6)
> newV
[1] 1.0 2.0 2.6
Joko
la source
Je vous suggère de formater correctement les données que vous avez affichées. Il semble que vous ayez manqué des sauts de ligne.
Chinmay Patil
Je veux une dispute. Ligne «1» et non la colonne «a».
Joko
Existe-t-il un moyen d'appliquer cela à toutes les lignes d'une trame de données et de fusionner ainsi tous les vecteurs en un seul vecteur?
stephanmg
1
@stephanmg: Qu'en est- il quelque chose comme: c(t(as.matrix(df)))?
Andri Signorell
Andri: Cela fonctionne, même si je pourrais le résoudre différemment aussi.
stephanmg

Réponses:

154

Lorsque vous extrayez une seule ligne d'un bloc de données, vous obtenez un bloc de données d'une ligne. Convertissez-le en vecteur numérique:

as.numeric(df[1,])

Comme le suggère @Roland, unlist(df[1,])convertira la trame de données d'une ligne en un vecteur numérique sans supprimer les noms. Il unname(unlist(df[1,]))existe donc une autre façon, légèrement plus explicite, d'arriver au même résultat.

Comme @Josh le commente ci-dessous, si vous avez un bloc de données non entièrement numérique (alphabétique, factoriel, mixte ...), vous en avez besoin à la as.character(df[1,])place.

Ben Bolker
la source
il pourrait s'agir de +1 (ou de 0 votes contre) au PO pour avoir donné un code illustrant clairement ce qu'il voulait, même si le texte et le titre de la question étaient déformés ...
Ben Bolker
@ChinmayPatil, quelles sont leurs autres options? Leur exemple de code donne certainement l'impression que c'est ce qu'ils veulent.
Ben Bolker
2
Il faut noter qu'une trame de données est déjà un vecteur et donc as.vector voit que c'est un vecteur de mode "liste" et ne fait rien. Pour faciliter la compréhension des mécanismes sous-jacents, essayez as.vector (df [1,], mode = "numeric") qui est plus illustratif. C'est ce que fait as.numeric.
1
aucun problème. Je dis seulement que pour ce problème, ils donnent exactement la même réponse.
Ben Bolker
1
Peut-être a-t-il été changé entre-temps, mais aujourd'hui unlist permet de supprimer des noms: identical(unlist(df[1,], use.names = FALSE), as.numeric(df[1,])) (et btw df n'est toujours pas un nom sensé pour un data.frame ... ;-))
Andri Signorell
45

Je recommande unlist, qui garde les noms.

unlist(df[1,])
  a   b   c 
1.0 2.0 2.6 

is.vector(unlist(df[1,]))
[1] TRUE

Si vous ne voulez pas de vecteur nommé:

unname(unlist(df[1,]))
[1] 1.0 2.0 2.6
Roland
la source
7

Si vous ne voulez pas passer au numérique, vous pouvez essayer ceci.

> as.vector(t(df)[,1])
[1] 1.0 2.0 2.6
Chinmay Patil
la source
3
cela ne fait pas de sens pour moi: str(as.vector(t(df)[,1]))est num [1:3] 1 2 2.6, par exemple votre code ne convertir les résultats à un vecteur numérique ...
Ben Bolker
2
spécifiquement, lorsque vous utilisez t(df)R contraint la trame de données à une matrice, dans ce cas une matrice numérique car tous les éléments sont numériques. [,1]Extrait ensuite la première colonne (un vecteur numérique, car la dimension redondante est automatiquement supprimée). as.vector()supprime simplement les noms (avec lesquels vous pouvez également faire unname()).
Ben Bolker
Cela semble également fonctionner pour les personnages. Mais vous avez raison sur la coersion. FWIW, ma solution fonctionne sur des trames de données de caractère aussi bien .. avec mise en garde de toutes les données converties à caractère
Chinmay Patil
2
Je dirais que la unname(unlist(x))solution est un peu meilleure (plus efficace et plus transparente).
Ben Bolker
as.vector(t(df)[,1])J'aime cela ! Exactement ce dont j'ai besoin!
Uther Pendragon
7

Voici une dplyroption basée:

newV = df %>% slice(1) %>% unlist(use.names = FALSE)

# or slightly different:
newV = df %>% slice(1) %>% unlist() %>% unname()
sbha
la source
2

Notez que vous devez faire attention si votre ligne contient un facteur. Voici un exemple:

df_1 = data.frame(V1 = factor(11:15),
                  V2 = 21:25)
df_1[1,] %>% as.numeric() # you expect 11 21 but it returns 
[1] 1 21

Voici un autre exemple (par défaut data.frame () convertit les caractères en facteurs)

df_2 = data.frame(V1 = letters[1:5],
                  V2 = 1:5)
df_2[3,] %>% as.numeric() # you expect to obtain c 3 but it returns
[1] 3 3
df_2[3,] %>% as.character() # this won't work neither
[1] "3" "3"

Pour éviter ce comportement, vous devez prendre soin du facteur avant de l'extraire:

df_1$V1 = df_1$V1 %>% as.character() %>% as.numeric()
df_2$V1 = df_2$V1 %>% as.character()
df_1[1,] %>% as.numeric()
[1] 11  21
df_2[3,] %>% as.character()
[1] "c" "3"
Rtist
la source
-3

Les colonnes de trames de données sont déjà des vecteurs, il suffit de les extraire. Notez que vous placez la colonne souhaitée après la virgule, pas avant:

> newV <- df[,1]
> newV
[1] 1 2 4 2

Si vous voulez vraiment une ligne, faites ce que Ben a dit et utilisez les mots correctement à l'avenir.

Jonathan Christensen
la source
mais je pense que l'OP veut la première ligne ?
Ben Bolker
1
@BenBolker Peut-être que oui ... J'ai juste supposé qu'il voulait ce que son titre et sa question disaient qu'il voulait.
Jonathan Christensen