Tutorial de R: Cómo importar datos a R

Obtén el libro completo
Practical R para comunicación de masas y periodismo MSRP $ 59.95 Verlo

Este artículo fue extraído de “Practical R for Mass Communication and Journalism” con permiso del editor. © 2019 por Taylor & Francis Group, LLC.

Antes de poder analizar y visualizar datos, debe introducirlos en R. Hay varias formas de hacerlo, según el formato de los datos y su ubicación.

Normalmente, la función que utiliza para importar datos depende del formato de archivo de los datos. En base R, por ejemplo, puede importar un archivo CSV con read.csv(). Hadley Wickham creó un paquete llamado readxl que, como era de esperar, tiene una función para leer archivos de Excel. Hay otro paquete, googlesheets, para extraer datos de las hojas de cálculo de Google.

Pero si no quieres recordar todo eso, está rio.

La magia de rio

“El objetivo de rio es hacer que la E / S de archivos de datos [importación / salida] en R sea lo más fácil posible mediante la implementación de tres funciones simples en estilo navaja suiza”, según la página de GitHub del proyecto. Esas funciones son import(), export()y convert().

Por lo tanto, el paquete rio sólo tiene una función para leer en muchos tipos diferentes de archivos: import(). Si es así import("myfile.csv"), sabe usar una función para leer un archivo CSV. import("myspreadsheet.xlsx")funciona de la misma manera. De hecho, rio maneja más de dos docenas de formatos, incluidos datos separados por tabulaciones (con la extensión .tsv), JSON, Stata y datos en formato de ancho fijo (.fwf).

Paquetes necesarios para este tutorial

  • Rio
  • htmltab
  • readxl
  • googlesheets
  • pacman
  • portero
  • rmiscutils (pm GitHub) o readr
  • tibble

Una vez que haya analizado sus datos, si desea guardar los resultados como un CSV, una hoja de cálculo de Excel u otros formatos, la export()función de rio puede manejar eso.

Si aún no tiene el paquete rio en su sistema, instálelo ahora con install.packages("rio").

He configurado algunos datos de muestra con los datos de las nevadas invernales de Boston. Puede dirigirse a //bit.ly/BostonSnowfallCSV y hacer clic derecho para guardar el archivo como BostonWinterSnowfalls.csv en su directorio de trabajo actual del proyecto R. Pero uno de los puntos de la creación de scripts es reemplazar el trabajo manual, tedioso o no, por una automatización que sea fácil de reproducir. En lugar de hacer clic para descargar, puede usar la download.filefunción de R con la sintaxis download.file("url", "destinationFileName.csv"):

download.file ("// bit.ly/BostonSnowfallCSV", "BostonWinterSnowfalls.csv")

Esto supone que su sistema redirigirá desde ese acceso directo de URL de Bit.ly y encontrará con éxito la URL del archivo real, //raw.githubusercontent.com/smach/NICAR15data/master/BostonWinterSnowfalls.csv. Ocasionalmente he tenido problemas para acceder a contenido web en equipos antiguos con Windows. Si tiene uno de esos y este enlace de Bit.ly no funciona, puede cambiar la URL real por el enlace de Bit.ly. Otra opción es actualizar su PC con Windows a Windows 10, si es posible, para ver si funciona.

Si desea que rio pueda importar datos directamente desde una URL, de hecho puede, y llegaré a eso en la siguiente sección. El objetivo de esta sección es practicar el trabajo con un archivo local.

Una vez que tenga el archivo de prueba en su sistema local, puede cargar esos datos en un objeto R llamado snowdata con el código:

snowdata <- rio :: import ("BostonWinterSnowfalls.csv")

Tenga en cuenta que es posible que rio le pida que vuelva a descargar el archivo en formato binario, en cuyo caso deberá ejecutar

download.file ("// bit.ly/BostonSnowfallCSV", "BostonWinterSnowfalls.csv", mode = "wb")

Asegúrese de utilizar las opciones de finalización de pestañas de RStudio. Si escribe rio::y espera, obtendrá una lista de todas las funciones disponibles. Escriba snowy espere, y debería ver el nombre completo de su objeto como una opción. Utilice las teclas de flecha hacia arriba y hacia abajo para moverse entre las sugerencias de autocompletar. Una vez que la opción que desea esté resaltada, presione la tecla Tab (o Enter) para que se agregue el nombre completo del objeto o función a su secuencia de comandos.

Debería ver que el objeto snowdataaparece en la pestaña de su entorno en el panel superior derecho de RStudio. (Si ese panel superior derecho muestra su historial de comandos en lugar de su entorno, seleccione la pestaña Entorno).

Taylor & Francis Group

snowdatadebe mostrar que tiene 76 “obs.” (observaciones o filas) y dos variables o columnas. Si hace clic en la flecha a la izquierda de snowdatapara expandir la lista, verá los dos nombres de columna y el tipo de datos que contiene cada columna. Son Wintercadenas de caracteres y la Totalcolumna es numérica. También debería poder ver los primeros valores de cada columna en el panel Entorno.

Taylor & Francis Group

Haga clic en la palabra snowdataen sí en la pestaña Entorno para obtener una vista más similar a una hoja de cálculo de sus datos. Puede obtener esa misma vista desde la consola R con el comando View(snowdata)(tiene que ser una V mayúscula en Vista view, no funcionará). Nota: snowdatano está entre comillas porque se refiere al nombre de un objeto R en su entorno. En el rio::importcomando anterior, BostonWinterSnowfalls.csv está entre comillas porque no es un objeto R; es un nombre de cadena de caracteres de un archivo fuera de R.

Taylor & Francis Group

Esta vista tiene un par de comportamientos similares a los de una hoja de cálculo. Haga clic en el encabezado de una columna para que se ordene por los valores de esa columna en orden ascendente; haga clic en el mismo encabezado de columna por segunda vez para ordenar en orden descendente. Hay un cuadro de búsqueda para encontrar filas que coincidan con ciertos caracteres.

Si hace clic en el icono Filtro, obtendrá un filtro para cada columna. La Wintercolumna de caracteres funciona como es de esperar, filtrando las filas que contienen los caracteres que escribe. Sin embargo, si hace clic en el Totalfiltro de la columna numérica, las versiones anteriores de RStudio muestran un control deslizante, mientras que las más nuevas muestran un histograma y un cuadro para filtrar .

Importar un archivo de la web

Si desea descargar e importar un archivo de la web, puede hacerlo si está disponible públicamente y en un formato como Excel o CSV. Tratar

snowdata <- rio :: import ("// bit.ly/BostonSnowfallCSV", formato)

Muchos sistemas pueden seguir la URL de redireccionamiento al archivo incluso después de mostrarle un mensaje de error, siempre que especifique el formato "csv"porque el nombre del archivo aquí no lo incluye .csv. Si el suyo no funciona, use la URL //raw.githubusercontent.com/smach/R4JournalismBook/master/data/BostonSnowfall.csv en su lugar.

rio también puede importar tablas HTML bien formateadas desde páginas web, pero las tablas deben tener un formato extremadamente bueno. Supongamos que desea descargar la tabla que describe las clasificaciones de gravedad del Servicio Meteorológico Nacional para las tormentas de nieve. La página del Índice de nevadas regionales de los Centros Nacionales de Información Ambiental tiene solo una tabla, muy bien diseñada, por lo que un código como este debería funcionar:

rsi_description <- rio :: import ("//www.ncdc.noaa.gov/snow-and-ice/rsi/", format = "html")

Tenga en cuenta nuevamente que debe incluir el formato, en este caso format="html". porque la URL en sí misma no da ninguna indicación sobre qué tipo de archivo es. Si la URL incluye un nombre de archivo con una .htmlextensión, rio lo sabría.

Sin embargo, en la vida real, los datos web rara vez aparecen de forma tan ordenada y aislada. Una buena opción para los casos que no están tan bien elaborados suele ser el paquete htmltab. Instálelo con install.packages("htmltab"). La función del paquete para leer una tabla HTML también se llama htmltab. Pero si ejecuta esto:

biblioteca (htmltab) citytable <- htmltab ("// en.wikipedia.org/wiki/List_of_United_States_cities_by_population") str (citytable)

ve que no tiene la tabla correcta, porque el marco de datos contiene un objeto. Como no especifiqué qué tabla, extrajo la primera tabla HTML de la página. No resultó ser el que yo quería. No tengo ganas de importar todas las tablas de la página hasta que encuentre la correcta, pero afortunadamente tengo una extensión de Chrome llamada Table Capture que me permite ver una lista de las tablas en una página.

La última vez que verifiqué, la tabla 5 con más de 300 filas era la que quería. Si eso no funciona para usted ahora, intente instalar Table Capture en un navegador Chrome para verificar qué tabla desea descargar.

Lo intentaré de nuevo, especificando la tabla 5 y luego viendo qué nombres de columna están en la nueva tabla de ciudades. Tenga en cuenta que en el siguiente código, coloco el citytable <- htmltab()comando en varias líneas. Eso es para que no se exceda en los márgenes; puede mantener todo en una sola línea. Si el número de la tabla ha cambiado desde que se publicó este artículo, reemplácelo which = 5con el número correcto.

En lugar de usar la página en Wikipedia, puede reemplazar la URL de Wikipedia con la URL de una copia del archivo que creé. Ese archivo está en //bit.ly/WikiCityList. Para utilizar esa versión, el tipo bit.ly/WikiCityListen un navegador, y luego copiar la URL larga a la que apunta y el uso que en lugar de la URL Wikipedia en el código de abajo:

biblioteca (htmltab) citytable <- htmltab ("// en.wikipedia.org/wiki/List_of_United_States_cities_by_population", que = 5) colnames (citytable)

¿Cómo supe que whichera el argumento que necesitaba para especificar el número de la tabla? Leí el htmltabarchivo de ayuda usando el comando ?htmltab. Eso incluyó todos los argumentos disponibles. Escaneé las posibilidades y " whichun vector de longitud uno para la identificación de la tabla en el documento" parecía correcto.

Tenga en cuenta también que usé en colnames(citytable)lugar de names(citytable)ver los nombres de las columnas. Cualquiera funcionará. La base R también tiene la  rownames()función.

De todos modos, los resultados de la tabla son mucho mejores, aunque puede ver al ejecutar str(citytable)que un par de columnas que deberían ser números aparecieron como cadenas de caracteres. Puede ver esto chrjunto al nombre de la columna y entre comillas alrededor de valores como 8,550,405.

Esta es una de las pequeñas molestias de R: R generalmente no entiende que 8,550es un número. Yo mismo resolví este problema escribiendo mi propia función en mi propio paquete rmiscutils para convertir todas esas "cadenas de caracteres" que en realidad son números con comas de nuevo en números. Cualquiera puede descargar el paquete de GitHub y usarlo.

La forma más popular de instalar paquetes desde GitHub es usar un paquete llamado devtools. devtools es un paquete extremadamente poderoso diseñado principalmente para personas que desean escribir sus propios paquetes e incluye algunas formas de instalar paquetes desde otros lugares además de CRAN. Sin embargo, devtools generalmente requiere un par de pasos adicionales para instalar en comparación con un paquete típico, y quiero dejar las molestas tareas de administración del sistema hasta que sea absolutamente necesario.

Sin embargo, el paquete pacman también instala paquetes de fuentes no CRAN como GitHub. Si aún no lo ha hecho, instale pacman coninstall.packages("pacman").

La p_install_gh("username/packagerepo")función de pacman se instala desde un repositorio de GitHub.

p_load_gh("username/packagerepo")carga un paquete en la memoria si ya existe en su sistema, y ​​primero se instala y luego carga un paquete desde GitHub si el paquete no existe localmente.

Mi paquete de utilidades rmisc se puede encontrar en smach/rmiscutils. Ejecutar pacman::p_load_gh("smach/rmiscutils")para instalar mi paquete rmiscutils.

Nota: Un paquete alternativo para instalar paquetes de GitHub se llama remotes, que puede instalar a través de  install.packages("remotes"). Su objetivo principal es instalar paquetes desde repositorios remotos como GitHub. Puede consultar el archivo de ayuda con help(package="remotes").

Y posiblemente el más hábil de todos sea un paquete llamado githubinstall. Su objetivo es adivinar el repositorio donde reside un paquete. Instálelo a través de  install.packages("githubinstall"); entonces puedes instalar mi paquete rmiscutils usando  githubinstall::gh_install_packages("rmiscutils"). Se le preguntará si desea instalar el paquete en smach/rmisutils(lo hace).

Ahora que ha instalado mi colección de funciones, puede usar mi number_with_commas()función para cambiar esas cadenas de caracteres que deberían ser números nuevamente en números. Sugiero encarecidamente agregar una nueva columna al marco de datos en lugar de modificar una columna existente; esa es una buena práctica de análisis de datos, independientemente de la plataforma que esté utilizando.

En este ejemplo, llamaré a la nueva columna PopEst2017. (Si la tabla se ha actualizado desde entonces, utilice los nombres de columna adecuados).

biblioteca (rmiscutils) citytable $ PopEst2017 <- number_with_commas (citytable $ `estimación de 2017`)

Por cierto, mi paquete rmiscutils no es la única forma de lidiar con números importados que tienen comas. Después de crear mi paquete rmiscutils y su number_with_commas()función, nació el paquete tidyverse readr. readr también incluye una función que cadenas de caracteres vueltas en números, parse_number().

Después de instalar readr, puede generar números a partir de la columna de estimación de 2017 con readr:

citytable $ PopEst2017 <- readr :: parse_number (citytable $ `estimación de 2017`)

Una ventaja readr::parse_number()es que puede definir el suyo locale()para controlar cosas como la codificación y las marcas decimales, que pueden ser de interés para los lectores que no residen en los EE. UU. Ejecute ?parse_number para obtener más información.

Nota: Si no usó el completado con tabulación para la columna de estimación de 2017, es posible que haya tenido un problema con el nombre de esa columna si tiene un espacio en el momento en que está ejecutando este código. En mi código anterior, observe que hay comillas simples hacia atrás ( `) alrededor del nombre de la columna. Eso es porque el nombre existente tenía un espacio, que se supone que no debes tener en R. Ese nombre de columna tiene otro problema: comienza con un número, también generalmente con una R no-no. RStudio lo sabe y agrega automáticamente las comillas traseras necesarias alrededor del nombre con la pestaña de autocompletar.

Consejo adicional: hay un paquete R (¡por supuesto que lo hay!) Llamado janitor que puede corregir automáticamente los nombres de columnas problemáticos importados de una fuente de datos no compatible con R. Instálelo con install.packages("janitor"). Luego, puede crear nuevos nombres de columna limpios usando la clean_names()función del conserje .

Ahora, crearé un marco de datos completamente nuevo en lugar de alterar los nombres de las columnas en mi marco de datos original y ejecutaré clean_names () del conserje en los datos originales. Luego, verifique los nombres de las columnas del marco de datos con names():

citytable_cleaned <- conserje :: clean_names (citytable)

nombres (citytable_cleaned)

Verá que los espacios se han cambiado a guiones bajos, que son legales en los nombres de variables de R (al igual que los puntos). Y todos los nombres de columna que solían comenzar con un número ahora tienen un xal principio.

Si no quiere perder la memoria por tener dos copias de esencialmente los mismos datos, puede eliminar un objeto R de su sesión de trabajo con  rm()la función: rm(citytable).

Importar datos de paquetes

Hay varios paquetes que le permiten acceder a los datos directamente desde R. Uno es quantmod, que le permite extraer algunos datos financieros y del gobierno de EE. UU. Directamente en R.

Otro es el paquete de datos meteorológicos en CRAN. Puede extraer datos de la API Weather Underground, que tiene información de muchos países de todo el mundo. 

El paquete rnoaa, un proyecto del grupo rOpenSci, aprovecha varios conjuntos de datos de la Administración Nacional Oceánica y Atmosférica de EE. UU., Incluida información diaria sobre el clima, las boyas y las tormentas.

Si está interesado en los datos del gobierno estatal o local en los EE. UU. O Canadá, es posible que desee consultar RSocrata para ver si una agencia en la que está interesado publica datos allí. Todavía tengo que encontrar una lista completa de todos los conjuntos de datos de Socrata disponibles, pero hay una página de búsqueda en //www.opendatanetwork.com. Sin embargo, tenga cuidado: hay conjuntos cargados por la comunidad junto con datos oficiales del gobierno, así que verifique el propietario de un conjunto de datos y cargue la fuente antes de confiar en él para más práctica que R. "Conjunto de datos ODN" en un resultado significa que es un archivo subido por alguien del público en general. Los conjuntos de datos oficiales del gobierno tienden a residir en URL como //data.CityOrStateName.gov//data.CityOrStateName.us.

For more data-import packages, see my searchable chart at //bit.ly/RDataPkgs. If you work with US government data, you might be particularly interested in censusapi and tidycensus, both of which tap into US Census Bureau data. Other useful government data packages include eu.us.opendata from the US and European Union governments to make it easier to compare data in both regions, and cancensus for Canadian census data.

When the data’s not ideally formatted

In all these sample data cases, the data has been not only well-formatted, but ideal: Once I found it, it was perfectly structured for R. What do I mean by that? It was rectangular, with each cell having a single value instead of merged cells. And the first row had column headers, as opposed to, say, a title row in large font across multiple cells in order to look pretty—or no column headers at all.

Dealing with untidy data can, unfortunately, get pretty complicated. But there are a couple of common issues that are easy to fix.

Beginning rows that aren’t part of the data. If you know that the first few rows of an Excel spreadsheeet don’t have data you want, you can tell rio to skip one or more lines. The syntax is rio::import("mySpreadsheet.xlsx", skip=3) to exclude the first three rows. skip takes an integer.

There are no column names in the spreadsheet. The default import assumes the first row of your sheet is the column names. If your data doesn’t have headers, the first row of your data may end up as your column headers. To avoid that, use rio::import("mySpreadsheet.xlsx", col_names = FALSE) so R will generate default headers of X0, X1, X2, and so on. Or, use a syntax such as rio::import("mySpreadsheet.xlsx", col_names = c("City", "State", "Population")) to set your own column names.

If there are multiple tabs in your spreadsheet, the which argument overrides the default of reading in the first worksheet. rio::import("mySpreadsheet.xlsx", which = 2) reads in the second worksheet.

What’s a data frame? And what can you do with one?

rio imports a spreadsheet or CSV file as an R data frame. How do you know whether you’ve got a data frame? In the case of snowdata, class(snowdata) returns the class, or type, of object it is. str(snowdata) also tells you the class and adds a bit more information. Much of the info you see with str() is similar to what you saw for this example in the RStudio environment pane: snowdata has 76 observations (rows) and two variables (columns).

Data frames are somewhat like spreadsheets in that they have columns and rows. However, data frames are more structured. Each column in a data frame is an R vector, which means that every item in a column has to be the same data type. One column can be all numbers and another column can be all strings, but within a column, the data has to be consistent.

If you’ve got a data frame column with the values 5, 7, 4, and “value to come,” R will not simply be unhappy and give you an error. Instead, it will coerce all your values to be the same data type. Because “value to come” can’t be turned into a number, 5, 7, and 4 will end up being turned into character strings of "5", "7", and "4". This isn’t usually what you want, so it’s important to be aware of what type of data is in each column. One stray character string value in a column of 1,000 numbers can turn the whole thing into characters. If you want numbers, make sure you have them!

R does have a ways of referring to missing data that won’t screw up the rest of your columns: NA means “not available.”

Los marcos de datos son rectangulares: cada fila debe tener el mismo número de entradas (aunque algunas pueden estar en blanco) y cada columna debe tener el mismo número de elementos.

Las columnas de la hoja de cálculo de Excel se denominan normalmente con letras: Columna A, Columna B, etc. Puede hacer referencia a una columna de marco de datos con su nombre, utilizando la sintaxis dataFrameName$columnName. Entonces, si escribe snowdata$Totaly presiona Enter, verá todos los valores en la Totalcolumna, como se muestra en la siguiente figura. (Es por eso que cuando ejecuta el str(snowdata)comando, hay un signo de dólar antes del nombre de cada columna).

Taylor & Francis Group

A reminder that those bracketed numbers at the left of the listing aren’t part of the data; they’re just telling you what position each line of data starts with. [1] means that line starts with the first item in the vector, [10] the tenth, etc.

RStudio tab completion works with data frame column names as well as object and function names. This is pretty useful to make sure you don’t misspell a column name and break your script—and it also saves typing if you’ve got long column names.

Type snowdata$ and wait, then you see a list of all the column names in snowdata.

It’s easy to add a column to a data frame. Currently, the Total column shows winter snowfall in inches. To add a column showing totals in meters, you can use this format:

snowdata$Meters <- snowdata$Total * 0.0254

The name of the new column is on the left, and there’s a formula on the right. In Excel, you might have used =A2 * 0.0254 and then copied the formula down the column. With a script, you don’t have to worry about whether you’ve applied the formula properly to all the values in the column.

Now look at your snowdata object in the Environment tab. It should have a third variable, Meters.

Because snowdata is a data frame, it has certain data-frame properties that you can access from the command line. nrow(snowdata) gives you the numbers of rows and ncol(snowdata) the number of columns. Yes, you can view this in the RStudio environment to see how many observations and variables there are, but there will probably be times when you’ll want to know this as part of a script. colnames(snowdata) or names(snowdata) gives you the name of snowdata columns. rownames(snowdata) give you any row names (if none were set, it will default to character strings of the row number such as "1", "2", "3", etc.).

Some of these special dataframe functions, also known as methods, not only give you information but let you change characteristics of the data frame. So, names(snowdata) tells you the column names in the data frame, but

names(snowdata) <- c("Winter", "SnowInches", "SnowMeters")

changes the column names in the data frame.

You probably won’t need to know all available methods for a data frame object, but if you’re curious, methods(class=class(snowdata)) displays them. To find out more about any method, run the usual help query with a question mark, such as ?merge or ?subset.

When a number’s not really a number

ZIP codes are a good example of “numbers” that shouldn’t really be treated as such. Although technically numeric, it doesn’t make sense to do things like add two ZIP codes together or take an average of ZIP codes in a community. If you import a ZIP-code column, R will likely turn it into a column of numbers. And if you’re dealing with areas in New England where ZIP codes start with 0, the 0 will disappear.

I have a tab-delineated file of Boston ZIP codes by neighborhood, downloaded from a Massachusetts government agency, at //raw.githubusercontent.com/smach/R4JournalismBook/master/data/bostonzips.txt. If I tried to import it with zips <- rio::import("bostonzips.txt"), the ZIP codes would come in as 2118, 2119, etc. and not 02118, 02119, and so on.

This is where it helps to know a little bit about the underlying function that rio’s import() function uses. You can find those underlying functions by reading the import help file at ?import. For pulling in tab-separated files, import uses either fread() from the data.table package or base R’s read.table() function. The ?read.table help says that you can specify column classes with the colClasses argument.

Create a data subdirectory in your current project directory, then download the bostonzips.txt file with

download.file("//raw.githubusercontent.com/smach/R4JournalismBook/master/data/bostonzips.txt", "data/bostonzips.txt")

If you import this file specifying both columns as character strings, the ZIP codes will come in properly formated:

zips <- rio::import("data/bostonzips.txt", colClasses = c("character”", "character")) str(zips)

Note that the column classes have to be set using the c() function, c("character", "character"). If you tried colClasses, "character", you’d get an error message. This is a typical error for R beginners, but it shouldn’t take long to get into the c() habit.

A save-yourself-some-typing tip: Writing out c("character", "character") isn’t all that arduous; but if you’ve got a spreadsheet with 16 columns where the first 14 need to be character strings, this can get annoying. R’s rep() function can help. rep(), as you might have guessed, repeats whatever item you give it however many times you tell it to, using the format rep(myitem, numtimes). rep("character", 2) is the same as c("character", "character"), so colClasses = rep("character", 2) is equivalent to colClasses = c("character", "character") . And, colClasses = c(rep("character", 14), rep("numeric", 2)) sets the first 14 columns as character strings and the last two as numbers. All the names of column classes here need to be in quotation marks because names are character strings.

I suggest you play around a little with rep() so you get used to the format, since it’s a syntax that other R functions use, too.

Easy sample data

R comes with some built-in data sets that are easy to use if you want to play around with new functions or other programming techniques. They’re also used a lot by people teaching R, since instructors can be sure that all students are starting off with the same data in exactly the same format.

Type data() to see available built-in data sets in base R and whatever installed packages are currently loaded. data(package = .packages(all.available = TRUE)) from base R displays all possible data sets from packages that are installed in your system, whether or not they’re loaded into memory in your current working session.

You can get more information about a data set the same way you get help with functions: ?datasetname or help("datasetname"). mtcars and iris are among those I’ve seen used very often.

If you type mtcars, the entire mtcars data set prints out in your console. You can use the head() function to look at the first few rows with head(mtcars).

You can store that data set in another variable if you want, with a format like cardata <- mtcars.

Or, running the data function with the data set name, such as data(mtcars), loads the data set into your working environment.

One of the most interesting packages with sample data sets for journalists is the fivethirtyeight package, which has data from stories published on the FiveThirtyEight.com website. The package was created by several academics in consultation with FiveThirtyEight editors; it is designed to be a resource for teaching undergraduate statistics.

Prepackaged data can be useful—and in some cases fun. In the real world, though, you may not be using data that’s quite so conveniently packaged.

Create a data frame manually in R

Chances are, you’ll often be dealing with data that starts off outside of R and you import from a spreadsheet, CSV file, API, or other source. But sometimes you might just want to type a small amount of data directly into R, or otherwise create a data frame manually. So let’s take a quick look at how that works.

R data frames are assembled column by column by default, not one row at a time. If you wanted to assemble a quick data frame of town election results, you could create a vector of candidate names, a second vector with their party affiliation, and then a vector of their vote totals:

candidates <- c("Smith", "Jones", "Write-ins", "Blanks")

party <- c("Democrat", "Republican", "", "")

votes <- c(15248, 16723, 230, 5234)

Remember not to use commas in your numbers, like you might do in Excel.

To create a data frame from those columns, use the data.frame() function and the synatx data.frame(column1, column2, column3).

myresults <- data.frame(candidates, party, votes)

Check its structure with str():

str(myresults)

While the candidates and party vectors are characters, the candidates and party data frame columns have been turned into a class of R objects called factors. It’s a bit too in-the-weeds at this point to delve into how factors are different from characters, except to say that

  1. Factors can be useful if you want to order items in a certain, nonalphabetical way for graphing and other purposes, such as Poor is less than Fair is less than Good is less than Excellent.
  2. Factors can behave differently than you might expect at times. I recommend sticking with character strings unless you have a good reason to specifically want factors.

You can keep your character strings intact when creating data frames by adding the argument stringsAsFactors = FALSE:

myresults <- data.frame(candidates, party, votes, stringsAsFactors = FALSE) str(myresults)

Now, the values are what you expected.

There’s one more thing I need to warn you about when creating data frames this way: If one column is shorter than the other(s), R will sometimes repeat data from the shorter column—whether or not you want that to happen.

Say, for example, you created the election results columns for candidates and party but only entered votes results for Smith and Jones, not for Write-ins and Blanks. You might expect the data frame would show the other two entries as blank, but you’d be wrong. Try it and see, by creating a new votes vector with just two numbers, and using that new votes vector to create another data frame:

votes <- c(15248, 16723)

myresults2 <- data.frame(candidates, party, votes)

str(myresults2)

That’s right, R reused the first two numbers, which is definitely not what you’d want. If you try this with three numbers in the votes vector instead of two or four, R would throw an error. That’s because each entry couldn’t be recycled the same number of times.

If by now you’re thinking, “Why can’t I create data frames that don’t change strings into factors automatically? And why do I have to worry about data frames reusing one column’s data if I forget to complete all the data?” Hadley Wickham had the same thought. His tibble package creates an R class, also called tibble, that he says is a “modern take on data frames. They keep the features that have stood the test of time, and drop the features that used to be convenient but are now frustrating.”

If this appeals to you, install the tibble package if it’s not on your system and then try to create a tibble with

myresults3 <- tibble::tibble(candidates, party, votes)

and you’ll get an error message that the votes column needs to be either 4four items long or one item long (tibble() will repeat a single item as many times as needed, but only for one item).

Put the votes column back to four entries if you’d like to create a tibble with this data:

library(tibble)

votes <- c(15248, 16723, 230, 5234)

myresults3 <- tibble(candidates, party, votes)

str(myresults3)

It looks similar to a data frame—in fact, it is a data frame, but with some special behaviors, such as how it prints. Also notice that the candidates column is character strings, not factors.

If you like this behavior, go ahead and use tibbles. However, given how prevelant conventional data frames remain in R, it’s still important to know about their default behaviors.

Exporting data

Often after you’ve wrangled your data in R, you want to save your results. Here are some of the ways to export your data that I tend to use most:

Save to a CSV file with rio::export(myObjectName, file="myFileName.csv") and to an Excel file with rio::export(myObjectName, file="myFileName.xlsx"). rio understands what file format you want based on the extension of the file name. There are several other available formats, including .tsv for tab-separated data, .json for JSON, and .xml for XML.

Save to an R binary object that makes it easy to load back into R in future sessions. There are two options.

Generic save() saves one or more objects into a file, such as save(objectName1, objectName2, file="myfilename.RData"). To read this data back into R, you just use the command load("myfilename.RData") and all the objects return with the same names in the same state they had before.

You can also save a single object into a file with saveRDS(myobject, file="filename.rds"). The logical assumption is that loadRDS would read the file back in, but instead the command is readRDS—and in this case, just the data has been stored, not the object name. So, you need to read the data into a new object name, such as mydata <- readRDS("filename.rds").

There’s a third way of saving an R object specifically for R: generating the R commands that would recreate the object instead of the object with final results. The base R functions for generating an R file to recreate an object are dput() or dump(). However, I find rio::export(myobject, "mysavedfile.R") even easier to remember.

Finally, there are additional ways to save files that optimize for readability, speed, or compression, which I mention in the additional resources section at the end of this article.

You can also export an R object into your Windows or Mac clipboard with rio: rio::export(myObjectName, format). And, you can import data into R from your clipboard the same way: rio::import(file).

Bonus: rio’s convert() function lets you—you guessed it—convert one file type to another without having to manually pull the data into and then out of R. See ?convert for more info.

Final point: RStudio lets you click to import a file, without having to write code at all. This isn’t something I recommend until you’re comfortable importing from the command line, beause I think it’s important to understand the code behind importing. But, I admit this can be a handy shortcut.

In the Files tab of RStudio’s lower right pane, navigate to the file you want to import and click it. You’ll see an option to either View File or Import Dataset. Choose Import Dataset to see a dialog that previews the data, lets you modify how the data is imported, and previews the code that will be generated.

Make whatever changes you want and click Import, and your data will be pulled into R.

Additional resources

rio alternatives. While rio is a great Swiss Army knife of file handling, there may be times when you want a bit more control over how your data is pulled into or saved out of R. In addition, there have been times when I’ve had a challenging data file that rio choked on but another package could handle it. Some other functions and packages you may want to explore:

  • Base R’s read.csv() and read.table() to import text files (use ?read.csv and ?read.table to get more information). stringsAsFactors = FALSE is needed with these if you want to keep your character strings as character strings. write.csv() saves to CSV.
  • rio uses Hadley Wickham’s readxl package for reading Excel files. Another alternative for Excel is openxlsx, which can write to an Excel file as well as read one. Look at the openxlsx package vignettes for information about formatting your spreadsheets as you export.
  • Wickham’s readr package is also worth a look as part of the “tidyverse.” readr includes functions to read CSV, tab-separated, fixed-width, web logs, and several other types of files. readr prints out the type of data it has determined for each column—integer, character, double (non-whole numbers), etc. It creates tibbles.

Import directly from a Google spreadsheet. The googlesheets package lets you import data from a Google Sheets spreadsheet, even if it’s private, by authenticating your Google account. The package is available on CRAN; install it via install.packages("googlesheets"). After loading it with library("googlesheets"), read the excellent introductory vignette. At the time of this writing, the intro vignette was available in R at vignette("basic-usage", package="googlesheets"). If you don’t see it, try help(package="googlesheets") and click the User Guides, Package Vignettes and Other Documentation link for available vignettes, or look at the package information on GitHub at //github.com/jennybc/googlesheets.

Scrape data from Web pages with the rvest package and SelectorGadget browser extension or JavaScript bookmarklet. SelectorGadget helps you discover the CSS elements of data you want to copy that are on an HTML page; then rvest uses R to find and save that data. This is not a technique for raw beginners, but once you’ve got some R experience under your belt, you may want to come back and revisit this. I have some instructions and a video on how to do this at //bit.ly/Rscraping. RStudio has a webinar available on demand as well.

Alternatives to base R’s save and read functions. If you are working with large data sets, speed may become important to you when saving and loading files. The data.table package has a speedy fread() function, but beware that resulting objects are data.tables and not plain data frames; some behaviors are different. If you want a conventional data frame, you can get one with the as.data.frame(mydatatable) syntax. The data.table package’s fwrite() function is aimed at writing to a CSV file considerably faster than base R’s write.csv().

Otros dos paquetes pueden resultar de interés para almacenar y recuperar datos. El paquete de plumas se guarda en un formato binario que se puede leer en R o Python. Además, los primeros paquetes read.fst()y write.fst()ofrecen guardar y cargar rápidamente objetos de marco de datos R, además de la opción de compresión de archivos.