Converte una riga di un frame di dati in vettore


116

Voglio creare un vettore da una riga di un frame di dati. Ma non voglio avere nomi di righe e colonne. Ho provato diverse cose ... ma non ho avuto fortuna.

Questo è il mio data frame:

> 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

Provai:

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

Ma voglio davvero qualcosa di simile a questo:

> newV <- c( 1,2,2.6)
> newV
[1] 1.0 2.0 2.6

Ti suggerisco di formattare i dati che hai mostrato correttamente. Sembra che ti manchino alcune interruzioni di riga.
Chinmay Patil

Voglio una fila. Riga "1" e non colonna "a".
Joko

C'è un modo per applicarlo a tutte le righe di un frame di dati e quindi unire tutti i vettori in un unico vettore?
stephanmg

1
@stephanmg: Che dire qualcosa come: c(t(as.matrix(df)))?
Andri Signorell

Andri: Funziona, anche se potrei risolverlo in modo diverso.
stephanmg

Risposte:


154

Quando estrai una singola riga da un frame di dati, ottieni un frame di dati di una riga. Convertilo in un vettore numerico:

as.numeric(df[1,])

Come suggerisce @Roland, unlist(df[1,])convertirà il data frame di una riga in un vettore numerico senza far cadere i nomi. Quindi unname(unlist(df[1,]))è un altro modo leggermente più esplicito per ottenere lo stesso risultato.

Come commenta @Josh di seguito, se hai un frame di dati non completamente numerico (alfabetico, fattoriale, misto ...), devi as.character(df[1,])invece.


potrebbe essere +1 (o 0 voti
negativi) all'OP

@ChinmayPatil, quali sono le loro altre opzioni? Il loro esempio di codice fa sicuramente sembrare che sia quello che vogliono.
Ben Bolker

2
Va notato che un data frame è già un vettore e quindi as.vector lo vede è un vettore di modalità "list" e non fa nulla. Per facilitare la comprensione dei meccanismi sottostanti prova as.vector (df [1,], mode = "numeric") che è più illustrativo. Questo è ciò che fa as.numeric.

1
nessun problema. Sto solo affermando che per questo problema danno esattamente la stessa risposta.
Ben Bolker

1
Potrebbe essere stato cambiato nel frattempo, ma oggi unlist consente di eliminare i nomi: identical(unlist(df[1,], use.names = FALSE), as.numeric(df[1,])) (e btw df ancora non è un nome sensato per un data.frame ... ;-))
Andri Signorell

45

Mi raccomando unlist, che mantiene i nomi.

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

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

Se non vuoi un vettore con nome:

unname(unlist(df[1,]))
[1] 1.0 2.0 2.6

7

Se non vuoi cambiare in numerico puoi provare questo.

> as.vector(t(df)[,1])
[1] 1.0 2.0 2.6

3
questo non ha molto senso per me: str(as.vector(t(df)[,1]))è num [1:3] 1 2 2.6, vale a dire il codice non convertire i risultati ad un vettore numerico ...
Ben Bolker

2
in particolare, quando si utilizza t(df)R, il data frame viene convertito in una matrice, in questo caso una matrice numerica perché tutti gli elementi sono numerici. Quindi [,1]estrae la prima colonna (un vettore numerico, perché la dimensione ridondante viene automaticamente eliminata). as.vector()rilascia solo i nomi (cosa che potresti fare anche con unname()).
Ben Bolker

Sembra funzionare anche per i personaggi. Ma hai ragione riguardo alla coersione. FWIW, la mia soluzione funzionerà anche sui frame di dati dei personaggi .. con l'avvertenza di tutti i dati convertiti in caratteri
Chinmay Patil

2
Direi che la unname(unlist(x))soluzione è un po 'migliore (più efficiente e più trasparente).
Ben Bolker

as.vector(t(df)[,1])Lo adoro ! Esattamente quello che mi serve!
Uther Pendragon

7

Ecco dplyrun'opzione basata:

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

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

2

Nota che devi stare attento se la tua riga contiene un fattore. Ecco un esempio:

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

Ecco un altro esempio (per impostazione predefinita data.frame () converte i caratteri in fattori)

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"

Per prevenire questo comportamento, è necessario occuparsi del fattore, prima di estrarlo:

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"

-3

Le colonne di frame di dati sono già vettori, devi solo estrarle. Nota che inserisci la colonna che desideri dopo la virgola, non prima di essa:

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

Se vuoi davvero litigare, fai quello che ha detto Ben e usa le parole correttamente in futuro.


ma penso che l'OP voglia la prima fila ?
Ben Bolker

1
@BenBolker Forse è così ... ho solo pensato che volesse quello che il suo titolo e la domanda dicevano che voleva.
Jonathan Christensen
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.