Изучив основные объекты в R, мы можем перейти к объектам, ради которых многие и начинают изучать R, а именно, к базам данных (точнее, к таблицам, просто в социально-экономических науках эти термины отождествляют, хотя, строго говоря, база данных - это набор связанных между собой таблиц). Но прежде необходимо научиться загружать файлы с данными, чтобы было с чем работать.

Работа с файлами

Загрузка данных в R

Напоминание. Если мы не хотим прописывать слишком длинный путь к файлу, файл с данными можно сохранить сразу в рабочую папку (папку, из которой запускается R). Тогда при попытке открыть файл с заданным названием R будет искать его в этой папке. Узнать, какая папка является рабочей, можно с помощью функции getwd():

getwd() # wd - от working directory
## [1] "/Users/allat/Desktop/data-l3"

Рабочую папку можно изменить. Например, так:

setwd("C:/AllaT/Рабочий стол/")

Для начала загрузим в R «простые» текстовые файлы. «Простые» в том смысле, что для их загрузки не требуется установки специальных библиотек.

csv-файлы

Формат csv (от comma separated values) - широко распространенный текстовый формат, который используется для представления табличных данных. В качестве разделителя, т.е. символа, который разделяет значения колонок, обычно используется запятая, как и следует из названия.

df <- read.csv("example1.csv")
#View(df) # посмотреть на базу данных, V - заглавная

Но иногда в качестве разделителя могут быть использованы другие символы (точка с запятой, пробел, табуляция). Если мы загрузим файл с другим разделителем и никак это не укажем, что загрузится совсем не то, что мы ожидали:

df1 <- read.csv("example2.csv")
#View(df1)

А если выставим нужный разделитель в качестве параметра, то все будет, как нужно:

df1 <- read.csv("example2.csv", sep = ";") # sep - от separator
#View(df1)

Если в файле есть текст на кириллице, могут возникнуть проблемы при чтении файла или при его отображении. Решения могут быть разными (зависит от системы, ее параметров и самого файла). Самое простое - специфицировать кодировку самого файла:

#df2 <- read.csv("example3.csv", encoding = "UTF-8")
#df2 <- read.csv("example4.csv", encoding = "WINDOWS-1251")

Обычно текст в кодировке UTF-8 встречается в файлах, созданных в Mac OS или Linux, а WINDOWS-1251 (или CP-1251) - в Windows.

Будем считать, что с csv-файлами разобрались.

txt-файлы

При работе с txt-файлами необходимо указывать, каким образом столбцы отделены друг от друга (аргумент sep, разделитель, как и в случае в csv-файлами), а также учитывать, что представляет собой первая строка: наблюдение или шапку таблицы (аргумент header). Откроем файл, в котором столбы разделены табуляцией и сравним, как он будет выглядеть при выставлении разных значений параметра header:

table1 <- read.table('example1.txt', sep='\t', header = TRUE)  
#View(table1) # header = T - первая строка читается как имя переменной

table2 <- read.table('example1.txt', sep='\t', header = FALSE)
#View(table2) # header = F - первая строка читается как наблюдение

Теперь перейдем к другим форматам.

файлы Excel

Чтобы спокойно загружать xls-файлы и xlsx-файлы можно установить соответствующие библиотеки xls (xlsx). С их установкой могут возникнуть проблемы: R будет писать что-то про rjava. Это обычно бывает, если на компьютере не установлена Java или установлена такая ее версия, которая конфликтует с R (например, недостаточно новая). Тогда Java можно поставить, скачав отсюда. После этого проблема должна исчезнуть.

install.packages("xlsx")

Теперь обратимся к этой библиотеке - иначе открыть файл мы не сможем:

library(xlsx)

Наконец, откроем сам файл. Не забудьте указать номер листа после запятой (даже если он всего один), иначе не сработает.

ex_data <- read.xlsx("example1.xlsx", 1)

Иногда даже с переустановленной Java библиотека xlsx не хочет загружаться. Тогда можно пойти другим путем: в правом верхнем углу RStudio во вкладке Environment выбрать Import Dataset-From Excel, выбрать файл на компьютере через Browse, вписать название переменной, в которую сохраняем таблицу в R (например, df) в поле Name и нажать Import. Если в файле Excel более одного листа, тогда в поле Sheet нужно указать номер нужного листа.

Код, который исполняется, когда мы выполняем эти действия вручную, выглядит следующим образом:

library(readxl)
Df <- read_excel("example1.xlsx")

файлы STATA

Для загрузки файлов STATA (файлы с расширением .dta) потребуется библиотека foreign.

install.packages("foreign")
library(foreign)

Теперь загрузим dta-файл.

stata_data <- read.dta("example1.dta")

файлы SPSS

Для загрузки файлов SPSS (файлы с расширением .sav) потребуется библиотека Hmisc.

install.packages("Hmisc")
library(Hmisc)

Загрузим sav-файл.

#sav_data <- spss.get("example1.sav")

Сохранение файлов

Выгружаются данные из R аналогичным образом, но только вместо read в названиях функций используется write. Например, сохраним базу df в csv-формате:

write.csv(df, "new_file.csv")

Работа с таблицами

Описание таблицы

Загрузим более содержательную таблицу. Таблицу, взятую с сайта IBM, содержащую данные об эффективности рекламных кампаний. Файл и codebook к ней можно найти здесь.

dat <- read.csv("marketing.csv")

Какую информацию о таблице мы можем получить?

Можем определить число наблюдений и число переменных в датафрейме. Узнать это можно точно так же, как и размерность матрицы, ведь число строк - это число наблюдений, а число столбцов - это число переменных.

dim(dat)
## [1] 548   7

Можем узнать гораздо больше - структуру датафрейма: число наблюдений и переменных, типы переменных и примеры значений, которые они принимают. Сделать это можно с помощью уже знакомой функции str():

str(dat)
## 'data.frame':    548 obs. of  7 variables:
##  $ MarketID        : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ MarketSize      : Factor w/ 4 levels "","Large","Medium",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ LocationID      : int  1 1 1 1 2 2 2 2 3 3 ...
##  $ AgeOfStore      : int  4 4 4 4 5 5 5 5 12 12 ...
##  $ Promotion       : int  3 3 3 3 2 2 2 2 1 1 ...
##  $ Week            : int  1 2 3 4 1 2 3 4 1 2 ...
##  $ SalesInThousands: num  33.7 35.7 29 39.2 27.8 ...

Также легко посмотреть на первые несколько значений:

head(dat)
##   MarketID MarketSize LocationID AgeOfStore Promotion Week
## 1        1     Medium          1          4         3    1
## 2        1     Medium          1          4         3    2
## 3        1     Medium          1          4         3    3
## 4        1     Medium          1          4         3    4
## 5        1     Medium          2          5         2    1
## 6        1     Medium          2          5         2    2
##   SalesInThousands
## 1            33.73
## 2            35.67
## 3            29.03
## 4            39.25
## 5            27.81
## 6            34.67

Или последние:

tail(dat)
##     MarketID MarketSize LocationID AgeOfStore Promotion Week
## 543       10      Large        919          2         1    3
## 544       10      Large        919          2         1    4
## 545       10      Large        920         14         2    1
## 546       10      Large        920         14         2    2
## 547       10      Large        920         14         2    3
## 548       10      Large        920         14         2    4
##     SalesInThousands
## 543            57.20
## 544            64.34
## 545            50.20
## 546            45.75
## 547            44.29
## 548            49.41

Обсуждение вывода описательных статистик для переменных в базе данных оставим на потом, разберем этот вопрос более подробно, когда начнем разведывательный анализ данных. А пока поговорим о чуть более продвинутых (но несложных!) вещах.

Пропущенные значения

Результаты, которые выдают нам функции str() и dim(), содержат только общую информацию о количестве наблюдений в таблице и не дают никакой информации о пропущенных значениях. Как это исправить? Для начала можно выяснить, сколько в базе неполностью заполненных строк. Функция complete.cases() выдает логический вектор, где TRUE означает полностью заполненную строку, а FALSE - содержащую пропуски (NAs).

head(complete.cases(dat)) # head - первые несколько значений
## [1] TRUE TRUE TRUE TRUE TRUE TRUE

Посчитаем, сколько полностью заполненных наблюдений:

sum(complete.cases(dat))
## [1] 529

Соответственно, остальные (из 548) - недозаполненные (содержащие NAs).

Посмотрим на незаполненные строки:

View(dat[!complete.cases(dat), ]) # ! отрицание

Для дальнейшей работы с пропущенными значениями нам понадобятся дополнительные библиотеки. Установим их. Можно устанавливать сразу несколько библиотек – оформить перечень необходимых библиотек в виде вектора, и тогда сразу после установки одной библиотеки начнется загрузка следующей.

install.packages(c("mice", "VIM"))

Обратимся к ним:

library(mice)
library(VIM)

Выведем графики, которые покажут, в каких переменных пропущенных значений больше всего и как выглядит таблица с пропущенными значениями (паттерны пропущенных значений).

На графике слева показано, с какой частотой встречаются пропущенные значения в той или иной переменной. На графике справа показано, в каких комбинациях эти пропущенные значения встречаются. Например, в нашем случае отсутствие ответов в AgeOfStore часто совпадает с отсутствием ответов в SalesInThousands (пропущенные значения отмечены красным цветом).

aggr(dat)

Следующий график отвечает за заполненность наблюдений (красным цветом отмечены пропущенные значения, остальное - заполненные значения, чем темнее цвет, тем больше значение). По вертикальной оси - номер строки в базе данных (id наблюдения).

matrixplot(dat) 

## 
## Click in a column to sort by the corresponding variable.
## To regain use of the VIM GUI and the R console, click outside the plot region.

На этом закончим, а в следующий раз познакомимся с более содержательными вещами, связанными с работой с таблицами.