Converter coluna data.frame em um vetor?


164

Eu tenho um quadro de dados como:

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)

Tentei o seguinte para converter uma das colunas em um vetor, mas não funciona:

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

Esta é a única solução que eu poderia encontrar, mas estou assumindo que deve haver uma maneira melhor de fazer isso:

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

Nota: Meu vocabulário acima pode estar desativado, por favor, corrija-me se estiver. Ainda estou aprendendo o mundo da R. Além disso, qualquer explicação sobre o que está acontecendo aqui é apreciada (por exemplo, relacionada ao Python ou a alguma outra linguagem ajudaria!)


5
Como você vê nas respostas, uma leitura cuidadosa ?'[.data.frame'o levará muito longe.
joran

Respostas:


208

Vou tentar explicar isso sem cometer erros, mas aposto que isso atrairá um ou dois esclarecimentos nos comentários.

Um quadro de dados é uma lista. Quando você define um quadro de dados usando o nome de uma coluna e [, o que você recebe é uma sub- lista (ou um quadro de sub-dados). Se você quiser a coluna atômica real, poderá usar [[, ou de alguma maneira confusa (para mim), o aframe[,2]que retorna um vetor, não uma sub-lista.

Portanto, tente executar esta sequência e talvez as coisas sejam mais claras:

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

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

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

6
+1 Isso é útil. Eu me acostumei a usar aframe[,"a2"]por causa da capacidade de usar isso com quadros de dados e matrizes e parece obter os mesmos resultados - um vetor.
Iterator

8
[..., drop = F]sempre retornará um quadro de dados
Hadley

1
Isso é particularmente bom saber porque a df$xsintaxe retorna um vetor. Eu usei essa sintaxe por um longo tempo, mas quando tive que começar a usar df['name']ou df[n]recuperar colunas, encontrei problemas ao tentar enviá-los para funções que esperavam vetores. Usar df[[n]]ou df[['x']]limpar as coisas corretamente.
R14 de

8
Por que as.vectorparece silenciosamente não ter efeito? Isso não deveria retornar um vetor ou falha conspicuamente?
bli

aframe[['a2']]é muito útil com sfobjetos, pois aframe[,"a2"]retornará duas colunas porque a coluna geométrica está incluída.
24518 Matt

41

Agora existe uma maneira fácil de fazer isso usando dplyr.

dplyr::pull(aframe, a2)

32

Você pode usar a $extração:

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

ou o suporte quadrado duplo:

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

21

Você não precisa as.vector(), mas precisa de indexação correta:avector <- aframe[ , "a2"]

A outra coisa a ter em atenção é a drop=FALSEopção 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: O lembrete de drop=FALSEé útil - isso me ajuda nos casos em que posso selecionar N colunas de um data.frame, nos casos em que N = 1.
Iterator

Uso isso quando não posso prever o número de colunas selecionadas e, caso uma coluna apareça, o resultado ainda será passado como data.frame com n colunas. Um vetor pode lançar uma chave de macaco nas funções abaixo da linha.
Roman Luštrik

11

Outra vantagem de usar o operador '[[' é que ele funciona tanto com data.frame quanto data.table. Portanto, se a função precisar ser executada para data.frame e data.table e você desejar extrair uma coluna dela como um vetor,

data[["column_name"]] 

é melhor.


8

Você pode tentar algo assim-

as.vector(unlist(aframe$a2))

Isso é bom se você quiser comparar duas colunas usando identical.
P-robot

5

Se você apenas usar o operador de extração, ele funcionará. Por padrão, [] define a opção drop=TRUE, que é o que você deseja aqui. Veja ?'['para mais detalhes.

>  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 listas para filtrar quadros de dados, independentemente de terem ou não um valor% em% uma lista.

Eu estava criando listas manualmente exportando um dataframe de 1 coluna para o Excel, onde adicionaria "", em torno de cada elemento, antes de colar na lista R: <- c ("el1", "el2", ...) que normalmente era seguido por FilteredData <- subconjunto (Dados, coluna% na lista%).

Depois de pesquisar o stackoverflow e não encontrar uma maneira intuitiva de converter um quadro de dados de 1 coluna em uma lista, agora estou postando minha primeira contribuição de 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

Também podemos converter genericamente colunas data.frame em um vetor simples. as.vectornão é suficiente, pois retém a classe e a estrutura data.frame; portanto, também precisamos extrair o primeiro (e único) elemento:

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

Todas as soluções sugeridas até o momento requerem códigos de coluna codificados. Isso os torna não genéricos (imagine aplicar isso aos argumentos da função).

Como alternativa, você pode, é claro, ler primeiro os nomes das colunas e depois inseri-los no código nas outras soluções.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.