Actualizado el 21 de Marzo del 2018 (Publicado el 16 de Diciembre del 2017)
702 visualizaciones desde el 16 de Diciembre del 2017
92,1 KB
4 paginas
Creado hace 16a (09/09/2008)
Introducci´on al procesamiento de datos en R
Instructor: Felipe Gonz´alez, ITAM.
Septiembre, 2008
Resumen. C´omo leer y escribir datos en R. C´omo almacenar datos en R y
extraer datos de objetos de R C´omo construir tablas agregadas y reorganizar
tablas.
Leer y escribir datos. Leer tablas de datos en los formatos usuales de tex-
to (separado por comas, ancho fijo) es f´acil. En el siguiente ejemplo leemos
de un archivo separado por comas con encabezado (nombres de las colum-
nas) que est´a en nuestro sistema. Cambiamos directorio de trabajo, leemos
los datos, e imprimimos la tabla:
> setwd("/Users/felipe/proyectos/foro_r/datos")
> mi_tabla <- read.table("mis_datos.csv", sep = ",", header = TRUE)
> print(mi_tabla)
ind var1
var2
1 rojo 0.095
2 rojo 3.221
3 verde -2.342
1
2
3
De manera similar podemos leer archivos de otros formatos usando la librer´ıa
foreign). Por ejemplo, para leer un archivo dbf hacemos:
> library(foreign)
> setwd("/Users/felipe/proyectos/foro_r/datos")
> so2_df<-read.dbf("2008SO2P.DBF")
> print(so2_df[1:4,1:3])
#S´olo imprime 4 renglones y 3 columnas
1 2008-01-01
2 2008-01-01
3 2008-01-01
4 2008-01-01
FECHA HORA MSO2VAL
0.010
0.016
0.013
0.012
1
2
3
4
Podemos leer directamente de bases de datos usando la librer´ıa RODBC y
comandos de SQL ([1]). En el siguiente ejemplo creamos una base de datos
test, cuya fuente es una hoja de Excel:
> library(RODBC)
> conex <- odbcConnect("test")
> hojas <- sqlTables(conex)
> print(hojas[, 3:4])
TABLE_NAME TABLE_TYPE
TABLE
TABLE
Colores
Hoja2
1
2
> query <- "SELECT * FROM Hoja2"
> resultado <- sqlQuery(conex, query)
> close(conex)
> print(resultado)
Ind Color
V
V
M
1
2
3
1
2
3
Todo el archivo se lee a la memoria en los ejemplos anterior, as´ı que no
siempre podemos hacer esto con archivos muy grandes. En estos casos, pode-
mos abrir conexiones y leer y procesar l´ıneas secuencialmente (n´otese tamb´ı´en
que con las primeras dos l´ıneas bajamos el archivo del internet movie data-
base):
> #url_base<-"ftp://ftp.sunet.se/pub/tv+movies/imdb/ratings.list.gz"
> #download.file(url_base,"ratings.list.gz")
> ratings_gz<-gzfile("ratings.list.gz","r") #Abrir conexi´on
> encabezado<-readLines(ratings_gz,27)
> lineas<-readLines(ratings_gz,4)
> close(ratings_gz)
> print(lineas)
#Leer l´ıneas 1-27
#Leer l´ıneas 28-31
[1] "New Distribution Votes Rank Title"
[2] "
[3] "
[4] "
0000000115 371002
0000000015 316612
0000000016 264079
9.1 Shawshank Redemption, The (1994)"
9.1 Godfather, The (1972)"
9.0 Dark Knight, The (2008)"
Tablas de datos en la memoria de R pueden guardarse como archivos delimi-
tados:
> write.table(lineas, file = "nuevo.csv", sep = ",", row.names = FALSE)
y podemos verificar leyendo de nuevo el archivo:
> nuevas_lineas <- read.table("nuevo.csv", sep = ",", header = TRUE)
> print(nuevas_lineas)
1
2
3
4
0000000115 371002
x
New Distribution Votes Rank Title
9.1 Shawshank Redemption, The (1994)
9.1 Godfather, The (1972)
9.0 Dark Knight, The (2008)
0000000015 316612
0000000016 264079
Mientras trabajemos con R, sin embargo, conviene m´as usar el formato in-
terno de R:
> save(lineas,resultado,file="mis_datosR.rdata")
> rm(list=ls()) #Borrar objetos de R en sesi´on
> load("mis_datosR.rdata")
> load("mis_datosR.rdata")
> head(resultado,2)
1
2
Ind Color
V
V
1
2
> ls()
[1] "lineas"
#Listar objetos de R en sesi´on
"resultado"
Listas en R. Los datos en R se almacenan en objetos. Los objetos con los
que m´as usualmente trabajamos son listas. Las listas son estructuras de datos
recursivas: son colecciones ordenadas de listas. Podemos crear una lista con
la funci´on list:
> manzana <- list(nombre = "manzana", peso = 36.2, tipo = "fruta")
> pera <- list(nombre = "pera", tipo = "fruta", peso = 25)
> print(manzana)
$nombre
[1] "manzana"
$peso
[1] 36.2
$tipo
[1] "fruta"
> frutas <- list(uno = manzana, dos = pera)
> names(manzana)
[1] "nombre" "peso"
> names(frutas)
[1] "uno" "dos"
"tipo"
donde la funci´on names nos da los nombres de las componentes de la lista.
Usando los nombres podemos extraer componentes de la lista de la siguiente
forma:
> manzana$tipo
[1] "fruta"
> manzana$peso
[1] 36.2
> pera$peso
[1] 25
> manzana$peso + pera$peso
[1] 61.2
aunque tambi´en podemos extraer las componentes con la notaci´on de doble
corchete:
> pera[[1]]
[1] "pera"
> manzana[[2]] + pera[[2]]
Error in manzana[[2]] + pera[[2]] :
non-numeric argument to binary operator
La ´ultima l´ınea nos da un error: no podemos sumar la componente 2 de
manzana con la componente 2 de pera. Este tipo de errores son comunes, y
pueden ser muy frustrantes para los principiantes de R. Cuando aparecen
estos errores, conviene checar los tipos de cada uno de los objetos sobre
los que estamos operando con la funci´on mode, que nos dice el tipo de las
componentes de cada objeto.
> mode(pera$tipo)
[1] "character"
> mode(manzana$peso)
[1] "numeric"
> mode(manzana)
[1] "list"
y el problema es que la suma no est´a definida para un objeto de tipo character
y uno de tipo numeric.
Modo y clase de objetos Los objetos at´omicos son aquellos cuyas compo-
nentes son todas de tipo numeric,character,logical, o complex. En el ejemplo
de arriba, vemos por ejemplo que pera$tipo y manzana$peso son at´omicos. Los
objetos at´omicos m´as importantes son los vectores y las matrices. Empeza-
mos construyendo un vector num´erico y uno de caracteres:
1
> x <- c(1.5, 2.2, -5)
> a <- c("manzana", "pera", "pl´atano")
> mode(x)
[1] "numeric"
> mode(a)
[1] "character"
Podemos juntar estos dos vectores en una lista
> mi_lista <- list(medida = x, fruta = a)
> mode(mi_lista)
[1] "list"
> print(mi_lista$medida)
[1] 1.5 2.2 -5.0
> print(mi_lista)
$medida
[1] 1.5 2.2 -5.0
$fruta
[1] "manzana" "pera"
"pl´atano"
y ya casi tenemos la estructura de datos m´as usual de R. Para crearla
usamos la funci´on data.frame:
> mis_datos <- data.frame(mi_lista)
> mode(mis_datos)
[1] "list"
> names(mis_datos)
[1] "medida" "fruta"
> mode(mi_lista)
[1] "list"
> names(mi_lista)
[1] "medida" "fruta"
Los resultados de an´alisis los podemos tratar de la misma forma:
> densidad<-density(sta_ursula,na.rm=TRUE) #Estimaci´on con kernel de densidad
> names(densidad)
[1] "x"
[7] "has.na"
"y"
"bw"
"n"
"call"
"data.name"
> head(densidad$x)
#Qu´e contiene la componente x
[1] -0.0018400768 -0.0016176107 -0.0013951447 -0.0011726786 -0.0009502126
[6] -0.0007277465
> class(densidad)
[1] "density"
> mode(densidad)
[1] "list"
> print(densidad)
#¿Qu´e hace print con este objeto?
Call:
density.default(x = sta_ursula, na.rm = TRUE)
Data: sta_ursula (4920 obs.);
Bandwidth 'bw' = 0.0006134
x
y
Min.
:-0.00184
1st Qu.: 0.02658
Median : 0.05500
Mean
: 0.05500
3rd Qu.: 0.08342
Max.
: 0.11184
Min.
:2.675e-06
1st Qu.:8.101e-02
Median :2.467e-01
Mean
:8.791e+00
3rd Qu.:1.411e+00
Max.
:1.265e+02
En resumen, 1) la estructura de datos m´as com´un en R es la lista: los con-
juntos de datos son listas de clase dataframe, y es com´un que los resultado
de los an´alisis sean listas con distintas clases, 2) Las funciones´de R muchas
veces son polim´orficas: dan resultados distintos seg´un la clase de los objetos
en los que se eval´uan, y 3) Cuando queremos extraer de objetos que tienen
modo de lista, usamos la notaci´on de $ mostrada arriba (¡aunque no es la
´unica y manera, y no siempre es la mejor!)
N´otese que cuando aunque el tipo de mis_datos sigue siendo lista, cuando hi-
cimos print(mis_datos) no obtuvimos el mismo resultado que cuando hicimos
print(mi_lista). La raz´on es que al usar la funci´on data.frame convertimos
a mi_lista en un objeto de una clase distinta:
M´as de funciones en R. Generalmente los objetos creados en R tienen
funciones accesoras ([2],[1]). Cuando ´estas existen, son la manera preferida
de extraer datos de objetos. Por ejemplo, consideramos las funciones acceso-
ras de lm, que representa un modelo lineal.
> class(mi_lista)
[1] "list"
> class(mis_datos)
[1] "data.frame"
y la funci´on print funciona de distinta manera seg´un la clase de su argumento.
En general, todos los objetos adem´as de tener un tipo o modo tienen una
clase. La clase es estructura adicional que determina, entre otras cosas, c´omo
aplican las funciones a ese objeto.
Obtener datos de objetos de R. Una gran parte de los objetos usuales
de R son listas. Esto incluye los marcos de datos o data frames, y los objetos
que dan como resultado distintos an´alisis. Veamos unos ejemplos:
> setwd("/Users/felipe/proyectos/foro_r/datos")
> so2_df <- read.table("2008SO2P2.csv", sep = ",", header = TRUE)
> mode(so2_df)
[1] "list"
> class(so2_df)
[1] "data.frame"
> modelo_lineal <- lm(stack.loss ~ Air.Flow, data = stackloss)
> class(modelo_lineal)
[1] "lm"
> print(modelo_lineal)
Call:
lm(formula = stack.loss ~ Air.Flow, data = stackloss)
Coefficients:
(Intercept)
-44.132
Air.Flow
1.020
Podemos ver qu´e funciones est´an definidas para los objetos lm:
> ## La funci´on apropos busca entre TODOS los objetos de R seg´un
> apropos('.*\\.lm$') #una expresi´on regular
[1] "anova.lm"
[5] "model.frame.lm" "model.matrix.lm" "plot.lm"
[9] "print.lm"
"residuals.lm"
"hatvalues.lm"
"anovalist.lm"
"rstandard.lm"
"kappa.lm"
"predict.lm"
"rstudent.lm"
[13] "summary.lm"
Asi que por ejemplo, para extraer los residuales obtenidos podemos hacer
La funci´on read.table produce un marco de datos. Las componentes son
> residuales <- residuals.lm(modelo_lineal)
> head(residuales)
> names(so2_df)
[1] "FECHA.D"
[5] "MSO2TAC.N.7.3" "MSO2EAC.N.7.3" "MSO2LLA.N.7.3"
"HORA.N.2.0"
"MSO2VAL.N.7.3" "MSO2SUR.N.7.3"
6
4.5072796 -0.4927204 4.6088262 8.8728473 -1.1271527 -1.1271527
1
2
3
4
5
y podemos extraerlas como explicamos arriba, quiz´a creando nuevos objetos,
y luego aplicarles funciones:
> sta_ursula <- so2_df$MSO2SUR.N.7.3
> head(sta_ursula, 20)
´Esta ´ultima l´ınea de c´odigo no funcionar´ıa si el objeto modelo_lineal fuera
de otra clase para la que tambi´en tiene sentido obtener residuales. Es mejor
llamar la versi´on
Comentarios de: Introducción al procesamiento de datos en R (0)
No hay comentarios