Я бы хотел использовать readr::read_csv
вместо read.csv
из-за его скорости и автоматического преобразования дат.Однако есть одна проблема с тем, как он обрабатывает числа, которые в основном являются целыми числами, с добавлением нескольких чисел с плавающей точкой.
Есть ли способ заставить его использовать col_double
для всех чисел, при этом все еще используя col_guess
для всех остальных столбцов?
Мне кажется, что угадывание col_integer - неоптимальный выбор разработчика пакета.Кажется, это часто случается с реальными данными для меня.Например, когда ненулевые значения редки.
Я открываю файлы, не зная заранее типов столбцов или имен.
Вот иллюстрация проблемы:
df<-data.frame(
i=as.integer(c(1:5)),
d=seq.Date(as.Date('2019-01-01'), length.out = 5, by=1),
mix = c('1','2','3.1','4','5'),
stringsAsFactors = F
)%>%as.tbl
write_csv(df, '~/temp.csv')
это хорошо! Значение 3.1 читается правильно.
read_csv('~/temp.csv')
# A tibble: 5 x 3
i d mix
<int> <date> <dbl>
1 1 2019-01-01 1
2 2 2019-01-02 2
3 3 2019-01-03 3.1
4 4 2019-01-04 4
5 5 2019-01-05 5
Фрейм данных из 50 тыс. Строк с десятичным значением в следующих строках.
df_large <-data.frame(
i = as.integer(c(1:(1e4))),
d=seq.Date(as.Date('2019-01-01'), length.out = 1e4, by=1),
mix = as.character(c(1:(1e4))),
stringsAsFactors = F
)%>%as.tbl
bind_rows(df_large, df)%>%tail(7)
# A tibble: 7 x 3
i d mix
<int> <date> <chr>
1 9999 2046-05-17 9999
2 10000 2046-05-18 10000
3 1 2019-01-01 1
4 2 2019-01-02 2
5 3 2019-01-03 3.1
6 4 2019-01-04 4
7 5 2019-01-05 5
это ПЛОХО! 3.1 теперь НС.
bind_rows(df_large, df)%>%write_csv(., '~/temp.csv')
read_csv('~/temp.csv')%>%tail(7)
# A tibble: 7 x 3
i d mix
<int> <date> <int>
1 9999 2046-05-17 9999
2 10000 2046-05-18 10000
3 1 2019-01-01 1
4 2 2019-01-02 2
5 3 2019-01-03 NA
6 4 2019-01-04 4
7 5 2019-01-05 5
это работает, но как мне установить guess_max заранее.
read_csv('~/temp.csv', guess_max = 1e5)%>%as.tbl%>%tail(7)
# A tibble: 7 x 3
i d mix
<int> <date> <dbl>
1 9999 2046-05-17 9999
2 10000 2046-05-18 10000
3 1 2019-01-01 1
4 2 2019-01-02 2
5 3 2019-01-03 3.1
6 4 2019-01-04 4
7 5 2019-01-05 5
По мере роста guess_max увеличивается и время выполнения.Похоже, передискретизация.
system.time(read_csv('~/temp.csv', guess_max = 1e5)%>%as.tbl%>%tail(7))
user system elapsed
0.020 0.001 0.022
system.time(read_csv('~/temp.csv', guess_max = 1e7)%>%as.tbl%>%tail(7))
user system elapsed
0.321 0.010 0.332
system.time(read_csv('~/temp.csv', guess_max = 1e9)%>%as.tbl%>%tail(7))
user system elapsed
34.138 5.848 39.821
Это работает, но может быть> 30 столбцов, и я не набираю заранее.
read_csv('~/temp.csv', col_types = 'dDd')%>%as.tbl%>%tail(7)
data.table::fread
быстрый, хорошо обрабатывает числа, но не конвертирует даты.
data.table::fread('~/temp.csv')%>%as.tbl%>%tail(7)
# A tibble: 7 x 3
i d mix
<int> <chr> <dbl>
1 9999 2046-05-17 9999
2 10000 2046-05-18 10000
3 1 2019-01-01 1
4 2 2019-01-02 2
5 3 2019-01-03 3.1
6 4 2019-01-04 4
7 5 2019-01-05 5