До этого момента мы либо создавали какой-то набор данных, либо использовали какие-то встроенные датасеты. В реальной жизни все намного сложнее. Данные нужно откуда-то брать. Прежде чем говорить об источниках данных, давайте дадим определение. Импорт данных – это загрузка в среду R различных данных для последующей работы с ними. Важно понимать откуда мы берём данные. Обычно источником импорта выступают:
Директория – это место (папка), где находится ваш “проект”. То есть там лежит скрипт, данные, картинки и прочее. Когда вы хотите загрузить данные с файлика, вам нужно прописать путь к нему, но если он находится в вашей директории, то можно просто напиать его название.
После загрузки всех необходимых пакетов, нужно узнать в какой директории вы находитесь. Это можно сделать несколькими способами:
getwd()
.Зачастую, у каждого проекта своя директория, поэтому приходится часто их менять. Есть несколько способов это сделать:
setwd("~/Desktop/R")
, где в кавычках можно прописать путь к директории.Я рекомендую именно второй способ, потому что он быстрее , и вам не нужно знать путь. Чтобы проверить, что вы находитесь в нужной директории можно использовать функцию dir()
. Она показывает все объекты которые находятся в директории.
Формат .csv самый распространенный формат хранения данных в мире для анализа данных. Его можно получить, например, сохранив excel файл в формате csv(разделитель - запятая). Перед тем как подгружать файл, нужно открыть файл в текстовом редакторе и посмотреть его структуру. Нужно обратить внимание на:
Если вы часто работаете в разных директориях, советую прописать путь к файлу в отдельную переменную path
. Для этого можно использовать функцию file.path(‘~’, ‘data’, ‘data.csv’)
, но все таки лучше копировать путь из свойств файла. Также важно отметить про то, что Windows ставит слэш в обратную сторону.
Давайте разберем функцию read.csv()
. Можно вызвать справку и узнать об этой функции побольше.
Можно увидеть, что у этой функции достаточно много аргументов. Давайте посмотрим только на те, которые нам нужны.
read.csv(path, header = TRUE, sep = ",", stringAsFactors = TRUE, dec = '.')
Аргументы (дефолтное значение):
path
– путь к файлуheader
(TRUE
) – есть ли в файле наименования столбцовsep
(','
) – разделитель между переменнымиstringAsFactors
(TRUE
) – сделать ли столбец строковых переменных в факторныйdec
('.'
) – разделитель для числовых переменных (точка или запятая)У нас есть файлик friends.csv. Попробуем подгрузить его.
А давайте просто укажем файл и забьем на все эти параметры.
## Jack.19.M.10.May.2000.7 X6
## 1 Emma;21;F;22 February 1998;8 9
## 2 Henry;18;M;3 September 2001;8 0
## 3 Aria;20;F;26 June 1999;9 3
## 'data.frame': 3 obs. of 2 variables:
## $ Jack.19.M.10.May.2000.7: chr "Emma;21;F;22 February 1998;8" "Henry;18;M;3 September 2001;8" "Aria;20;F;26 June 1999;9"
## $ X6 : int 9 0 3
R неправильно прочитал файл. Он думает, что у нас есть всего два столбца. Почему так вышло? Если открыть файл в текстовом редакторе, то можно увидеть, что разделителем между переменными является ";"
.
Теперь мы поняли свою ошибку. Давайте её исправим
## Jack X19 M X10.May.2000 X7.6
## 1 Emma 21 F 22 February 1998 8,9
## 2 Henry 18 M 3 September 2001 8,0
## 3 Aria 20 F 26 June 1999 9,3
## 'data.frame': 3 obs. of 5 variables:
## $ Jack : chr "Emma" "Henry" "Aria"
## $ X19 : int 21 18 20
## $ M : chr "F" "M" "F"
## $ X10.May.2000: chr "22 February 1998" "3 September 2001" "26 June 1999"
## $ X7.6 : chr "8,9" "8,0" "9,3"
Ой! У нас всего 3 наблюдения, хотя было 4. Это произошло, так как первая строчка стала названием столбцом. Почему так вышло? Давайте исправим это.
## V1 V2 V3 V4 V5
## 1 Jack 19 M 10 May 2000 7,6
## 2 Emma 21 F 22 February 1998 8,9
## 3 Henry 18 M 3 September 2001 8,0
## 4 Aria 20 F 26 June 1999 9,3
## 'data.frame': 4 obs. of 5 variables:
## $ V1: chr "Jack" "Emma" "Henry" "Aria"
## $ V2: int 19 21 18 20
## $ V3: chr "M" "F" "M" "F"
## $ V4: chr "10 May 2000" "22 February 1998" "3 September 2001" "26 June 1999"
## $ V5: chr "7,6" "8,9" "8,0" "9,3"
Если взглянуть на данные, то кажется, что всё прекрасно. Но это не так!
Попробуем сделать всё так, как нужно!
data <- read.csv('data/friends.csv', sep = ';', header = FALSE,
dec = ',', stringsAsFactors = FALSE,
col.names = c('Name', 'Age', 'Gender', 'Birthday', 'Homework grade'))
data
## Name Age Gender Birthday Homework.grade
## 1 Jack 19 M 10 May 2000 7.6
## 2 Emma 21 F 22 February 1998 8.9
## 3 Henry 18 M 3 September 2001 8.0
## 4 Aria 20 F 26 June 1999 9.3
## 'data.frame': 4 obs. of 5 variables:
## $ Name : chr "Jack" "Emma" "Henry" "Aria"
## $ Age : int 19 21 18 20
## $ Gender : chr "M" "F" "M" "F"
## $ Birthday : chr "10 May 2000" "22 February 1998" "3 September 2001" "26 June 1999"
## $ Homework.grade: num 7.6 8.9 8 9.3
Все выглядит почти идеально. Изменим тип переменной Gender на факторный, а также переменную Birthday на дату.
# install.packages('lubridate')
library(lubridate)
data$Birthday <- dmy(data$Birthday)
data$Gender <- factor(data$Gender)
str(data)
## 'data.frame': 4 obs. of 5 variables:
## $ Name : chr "Jack" "Emma" "Henry" "Aria"
## $ Age : int 19 21 18 20
## $ Gender : Factor w/ 2 levels "F","M": 2 1 2 1
## $ Birthday : Date, format: "2000-05-10" "1998-02-22" ...
## $ Homework.grade: num 7.6 8.9 8 9.3
Если вы хотите использовать разделитель ;
, то можно использовать функцию read.csv2
, которая использует этот разделитель по умолчанию, а также dec = ","
.
Иногда бывают данные, где столбец это год. Например, у вас есть временной ряд за 1960 - 1976 года. Писать название каждого столбца утомительно. Можно воспользоваться функцией paste0
.
## [1] "year_1960" "year_1961" "year_1962" "year_1963" "year_1964" "year_1965"
## [7] "year_1966" "year_1967" "year_1968" "year_1969" "year_1970" "year_1971"
## [13] "year_1972" "year_1973" "year_1974" "year_1975" "year_1976"
Помним, что обычный data frame не терпит пробелов в названиях переменных. Можно ставить нижнее подчеркивание (_
).
Нужно сказать сначала то, что функции read.delim
и read.csv
это дочерние функции от функции read.table
. Как мы уже убедились read.csv
создан для файлов с расширением csv. А вот read.delim
создан для файлов с расширением .txt. Если у вас есть какое-то другое расширение, то вы можете использовать read.table
с нужными вам параметрами.
/t
– знак табуляции (один из видов разделителей). В read.delim
он используется по умолчанию.
data <- read.delim('data/friends.txt', dec = ',', header = FALSE,
stringsAsFactors = FALSE,
col.names = c('Name', 'Age', 'Gender', 'Birthday', 'Homework grade'))
data
## Name Age Gender Birthday Homework.grade
## 1 Jack 19 M 10 May 2000 7.6
## 2 Emma 21 F 22 February 1998 8.9
## 3 Henry 18 M 3 September 2001 8.0
## 4 Aria 20 F 26 June 1999 9.3
## 'data.frame': 4 obs. of 5 variables:
## $ Name : chr "Jack" "Emma" "Henry" "Aria"
## $ Age : int 19 21 18 20
## $ Gender : chr "M" "F" "M" "F"
## $ Birthday : chr "10 May 2000" "22 February 1998" "3 September 2001" "26 June 1999"
## $ Homework.grade: num 7.6 8.9 8 9.3
Аналогично есть функция read.delim2
.
Если открыть файл friends2.txt
можно увидеть, что разделитель это слэш (/
). С помощью read.table
мы можем задать нужный нам разделитель.
data <- read.table('data/friends2.txt', sep = '/', dec = ',',
header = FALSE, stringsAsFactors = FALSE,
col.names = c('Name', 'Age', 'Gender', 'Birthday', 'Homework grade'))
data
## Name Age Gender Birthday Homework.grade
## 1 Jack 19 M 10 May 2000 7.6
## 2 Emma 21 F 22 February 1998 8.9
## 3 Henry 18 M 3 September 2001 8.0
## 4 Aria 20 F 26 June 1999 9.3
## 'data.frame': 4 obs. of 5 variables:
## $ Name : chr "Jack" "Emma" "Henry" "Aria"
## $ Age : int 19 21 18 20
## $ Gender : chr "M" "F" "M" "F"
## $ Birthday : chr "10 May 2000" "22 February 1998" "3 September 2001" "26 June 1999"
## $ Homework.grade: num 7.6 8.9 8 9.3
Давайте для начала установим и прочитаем пакет, а также пакет dplyr
.
Зачем нам вообще этот пакет, ведь мы умеем читать файлы с расширением .csv, .txt и их разновидностями?.
Плюсы:
Здесь важно использовать определенную функцию для определенного разделителя. Мы рассмотрим функции read_csv()
и read_csv2()
.
Давайте попробуем подгрузить файл, который подгружали ранее.
data <- read_csv2('data/friends.csv',
col_names = c('Name', 'Age', 'Gender', 'Birthday', 'Homework grade'))
glimpse(data)
## Rows: 4
## Columns: 5
## $ Name <chr> "Jack", "Emma", "Henry", "Aria"
## $ Age <dbl> 19, 21, 18, 20
## $ Gender <chr> "M", "F", "M", "F"
## $ Birthday <chr> "10 May 2000", "22 February 1998", "3 September 2001…
## $ `Homework grade` <dbl> 7.6, 8.9, 8.0, 9.3
Все получилось! Видим, что оценка за ДЗ подгрузилась как число. Аргумент col_names
может принимать значение FALSE
, если у нас нет названий переменных.
Изучим 2 новых аргумента:
comment
– знак комментария в файлеskip
– количество строк, которые нужно пропуститьdata <- read_csv2('data/friends2.csv', comment = '#',
col_names = c('Name', 'Age', 'Gender', 'Birthday', 'Homework grade'))
Или можно просто пропустить 1 строку.
data <- read_csv2('data/friends2.csv', skip = 1,
col_names = c('Name', 'Age', 'Gender', 'Birthday', 'Homework grade'))
Функции этого пакета определяют тип переменных в столбце следующим образом: они берут первые 1000 наблюдений и используют к нему функцию guess_parser()
, которая определяет к какому типу относится переменная. А функция parse_guess()
преобразовывает вектор к нужному типу.
## [1] "logical"
## [1] TRUE FALSE
## [1] "double"
## [1] 1.20 2.12
Давайте проверим сокрость этого пакета. С помощью функции Sys.time()
будем измерять время загрузки файла. Будем использовать файл nir.csv. В нем имеются данные о российских корпоративных облигациях. Весит этот файл 50 мегабайт. Это средний размер файла, но уже здесь мы почувствуем разницу.
Посчитаем время использования функции read.csv()
:
## Time difference of 20.90118 secs
Видим приблизительно 20.9 секунды. Представьте, что вы меняете и запускаете код постоянно. Хотелось бы, чтобы загрузка занимала меньше времени.
Теперь посчитаем время использования аналогичной функции read_csv()
из пакета readr
:
## Time difference of 7.804004 secs
Время уменьшилось до 7.8 секунд!
В больших файлах иногда бывают проблемы. Например, первые 1000 значений NA
. А с 1001 идут вещественные числа. Столбцу дадут тип logical
. Можно увеличить количество значений с помощью аргумента guess_max
.
Можно увидеть, что появились предупреждения. Это связано с проблемой описанной выше. Эту проблему можно исправить с помощью парметра col_types
. С помощью него можно явно задать какого формата наша переменная.
data <- read_csv2('data/nir.csv', col_types = cols(
YLD_YTM_MID = col_double() ,
YLD_CNV_MID = col_double()
))
Иногда проблемных мест бывает очень много. Поэтому бывает полезно прочитать все переменные как строковые.
Почти в любых наборах данных, которые приходится импортировать бывают пропущенные значения. По умолчанию функция read_csv()
считает пропущенными значениями "" и “NA”. Это можно исправить с помощью аругмента na
. Представьте, что в наборе данных пропущенные значения помечаются как “UNKNOWN”, “NA” и "". Тогда можно преобразовать их следующим образом.
Можно подгружать файлы из интернета по url.
data <- read_csv2('https://raw.githubusercontent.com/ahmedushka7/R/master/docs/scripts/hse_data_analysis/sem_7/data/friends.csv', col_names = F)
data
## # A tibble: 4 x 5
## X1 X2 X3 X4 X5
## <chr> <dbl> <chr> <chr> <dbl>
## 1 Jack 19 M 10 May 2000 7.6
## 2 Emma 21 F 22 February 1998 8.9
## 3 Henry 18 M 3 September 2001 8
## 4 Aria 20 F 26 June 1999 9.3
Данные нужно уметь не только импортировать, но и экспортировать. Для этого можно использовать функцию write_csv()
. У нее имеется два важных аргумента:
x
– датасет (data frame), который у вас есть в памятиpath
– путь и название файла (если оставить только название файла, то файл сохранится в текущей директории)Давайте сохраним набор mtcars
.
Если вы планируете работать с вашим .csv файлом далее в excel, то рекомендуется использовать функцию write_excel_csv()
, чтобы избежать проблем с кодировкой. Она работает аналогично функции write_csv
.
Также существует функция write_csv2()
, которая сохраняет файл с разделителем ";"
.
В этих функциях можно также передать аргумент na
, в котором можно указать как должны выглядеть пропущенные значения в сохраняемом файле.
Пакет readr
по умолчанию работает с кодировкой UTF-8. Если вы работаете со старым файлом, у которого другая кодировка, то вы можете использовать функцию guess_encoding()
, которая может помочь узнать кодировку.
## # A tibble: 1 x 2
## encoding confidence
## <chr> <dbl>
## 1 ASCII 1
После того как вы узнали кодировку, вы можете передать ее в аргумент locale
.