До этого момента мы либо создавали какой-то набор данных, либо использовали какие-то встроенные датасеты. В реальной жизни все намного сложнее. Данные нужно откуда-то брать. Прежде чем говорить об источниках данных, давайте дадим определение. Импорт данных – это загрузка в среду 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.