Dataframes são uma generalização de matrizes onde cada coluna pode ser de um tipo ou classe diferente de dados. Neste sentido este é o objeto de R que mais se aproxima de uma planilha ou de um banco de dados.
Um dataframe pode conter nomes para as colunas, uma indicação de que dado está nela armazenado, e também um atributo especial chamado row.names que guarda informações sobre cada uma de suas linhas. Eles podem ser criados explicitamente com a função data.frame() ou através da transformação forçada de outros tipos de objetos, como as listas. Por sua vez eles podem ser transformados em matrizes data.matrix().
Muitas vezes um dataframe é carregado diretamente através da leitura de dados gravados previamente por meio de comandos como read.table() ou read.csv().
Vamos criar um dataframe contendo os dados de alunos, contendo um id, nome, idade e menção final (II, MI, MM, MS, SS), expostos na tabela seguinte:
| id | Nome | Idade | Menção |
|---|---|---|---|
| 1 | Paulo | 24 | MM |
| 2 | Joana | 23 | MS |
| 3 | Marcos | 19 | MM |
| 4 | Fred | 21 | II |
| 5 | Ana | 20 | MI |
Estes dados podem ser inseridos em um dataframe da seguinte forma:
> id <- 1:5
> nome <- c("Paulo", "Joana", "Marcos", "Fred", "Ana")
> idade <- c(24, 23, 19, 21, 20)
> mencao <- c("MM", "MS", "MM", "II", "MI" )
> alunos <- data.frame(id, nome, idade, mencao)
> alunos
id nome idade mencao
1 1 Paulo 24 MM
2 2 Joana 23 MS
3 3 Marcos 19 MM
4 4 Fred 21 II
5 5 Ana 20 MI
> # As entradas no frame podem ser consultadas de várias maneiras
> alunos["mencao"]
mencao
1 MM
2 MS
3 MM
4 II
5 MI
> alunos[c("nome", "mencao")]
nome mencao
1 Paulo MM
2 Joana MS
3 Marcos MM
4 Fred II
5 Ana MI
> alunos$mencao
[1] MM MS MM II MI
Levels: II MI MM MS
Observe que a coluna de menções (bem como a de nomes) foi transformada em um fator, não ordenado. Em situações em que o uso de um dataframe é recorrente as funções attach(), detach() e with() podem ser bastante úteis.
A função attach() informa ao interpretador de R qual é o dataframe default a que se referem os campos citados no código. A função detach() remove esta ligação. Seu uso é opcional mas é uma boa prática de programação que deve ser seguida.
attach(alunos)
The following objects are masked _by_ .GlobalEnv:
id, idade, mencao, nome
> id
[1] 1 2 3 4 5
> summary(idade)
Min. 1st Qu. Median Mean 3rd Qu. Max.
19.0 20.0 21.0 21.4 23.0 24.0
> table(mencao)
mencao
II MI MM MS
1 1 2 1
> detach(alunos)
Quando a função attach foi executada o interpretador informou que os campos id, idade, mencao, nome receberam máscaras para sua execução. Se outra variável previamente definida tinha o mesmo nome ela terá precedência na busca pelo interpretador (o que pode não ser o comportamento desejado). Para evitar tais possíveis conflitos podemos usar with(). Desta forma se garante que todos os comandos dentro das chaves se refiram à alunos.
> with(alunos, {
print(idade)
print(mencao)
})
[1] 24 23 19 21 20
[1] MM MS MM II MI
Levels: II MI MM MS
> # Se um único comando será usado as chaves são opcionais
with(alunos, summary(idade))
Min. 1st Qu. Median Mean 3rd Qu. Max.
19.0 20.0 21.0 21.4 23.0 24.0
> # a função summary faz uma estatística básica dos dados do argumento
> # Para que a atribuição continue existindo fora das chaves usamos <<-
> with(alunos, {
estatistica <<- summary(idade)
estat <- summary(idade)
})
> estatistica
Min. 1st Qu. Median Mean 3rd Qu. Max.
19.0 20.0 21.0 21.4 23.0 24.0
> estat
Error: object 'estat' not found
> # A mesma dataframe pode ser criada com a atribuição de labels
> # às suas linhas. No caso atribuímos o id a este label
> alunos <- data.frame(id, nome, idade, mencao, row.names = id)
> # Estes labels são usados para exibição de dados e gráficos
> # O dataframe pode ser ordenado por ordem de idade dos alunos
> alunos <- alunos[order(alunos$idade),]
> alunos
id nome idade mencao
3 3 Marcos 19 MM
5 5 Ana 20 MI
4 4 Fred 21 II
2 2 Joana 23 MS
1 1 Paulo 24 MM
> # O número de linhas e colunas podem ser obtidos
> nrow(alunos)
[1] 5
> ncol(alunos)
[1] 4
> # O data frame pode ser criado vazio, com os campos especificados
> df <- data.frame(id=numeric(0), nome=character(0), nota=numeric(0))
> df
[1] id nome nota
<0 rows> (or 0-length row.names)
> # e editado na janela edit
> df <- edit(df)
Funções usadas com dataframes:
| Função | Efeito |
|---|---|
| df <- data.frame(vetor1, ... , vetorn) | cria um dataframe |
| df[obj1] | exibe a coluna relativa à obj1 |
| attach(df) | liga as variáveis ao dataframe df |
| detach(df) | remove ligação ao dataframe df |
| with(df, {comandos}) | executa comandos com ligação ao dataframe df |
| summary(obj1) | retorna estatística básica dos dados de obj1 |
| nrow(df) | retorna número de linhas de df |
| ncow(df) | retorna número de colunas de df |
| edit(df) | abre uma janela para a edição do data frame |
edit() permite a edição de dados e dos nomes de campos de um data frame (ou de outros objectos de R, como vetores e matrizes).Ele, no entanto, deixa o objeto inalterado. Para que as alterações sejam passadas para o mesmo objeto devemos fazer
obj <- edit(obj).O mesmo resultado pode ser conseguido com o operador
fix():fix(obj) # alterações já ficam gravados em obj
Manipulando data frames com comandos SQL
Usando o pacote sqldf consultas podem ser feitas à um data frame usando consultas sql. Para isso instalamos o pacote e usamos a função sqldf(). Para exemplificar usamos o dataframe mtcars, que é carregado por padrão no R.
> # Nomes das colunas e primeiras 6 linhas de mtcars:
> head(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
> install.packages("sqldf") # instala pacote
> library(sqldf)
Loading required package: gsubfn
Loading required package: proto
> sql <- "SELECT * FROM mtcars WHERE gear=3 AND carb>2 ORDER BY mpg"
> carros <- sqldf(sql, row.names=TRUE)
> carros
mpg cyl disp hp drat wt qsec vs am gear carb
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
*.csv na sessão Aquisição de Dados.
Também é possível construir um data.frame aplicando uma consulta sql sobre um arquivo *.csv gravado no disco. Suponha que o seguinte conteúdo esteja gravado em um arquivo alunos.csv.
id, Nome, Sobrenome, Idade, Sexo 1, Marta, Rocha, 24, F 2, Pedro, Souza, 12, M 3, José, Marciano, 15, M 4, Joana, Santos, 21, F 5, Lucas, Pereira, 20, M
O código seguinte usa a função, read.csv.sql() para selecionar o nome e a idade dos alunos com idade superior a 20 anos, de dentro do arquivo.
> sql <- "SELECT Nome, Idade FROM alunos.csv WHERE Idade>20"
> rs <- read.csv.sql("alunos.csv", sql)
> # O seguinte data frame fica carregado:
> rs
Nome Idade
1 Marta 24
2 Joana 21
