read_csv对所有数值列使用col_double()代替

read_csv对所有数值列使用col_double()代替,r,tidyverse,readr,R,Tidyverse,Readr,我想使用readr::read_csv而不是read.csv,因为它速度快,并且可以自动转换日期。然而,它如何处理主要是整数的数字,并在其中撒上一些浮点数,存在一个问题 有没有办法强迫它对所有数字使用col\u double,而对所有其他列仍然使用col\u guess 对我来说,猜测col_integer似乎是软件包开发人员的次优选择。对我来说,在真实数据中似乎经常发生这种情况。例如,当很少出现非零时 我在打开文件之前不知道列类型或名称 read_csv('~/temp.csv', guess

我想使用
readr::read_csv
而不是
read.csv
,因为它速度快,并且可以自动转换日期。然而,它如何处理主要是整数的数字,并在其中撒上一些浮点数,存在一个问题

有没有办法强迫它对所有数字使用
col\u double
,而对所有其他列仍然使用
col\u guess

对我来说,猜测col_integer似乎是软件包开发人员的次优选择。对我来说,在真实数据中似乎经常发生这种情况。例如,当很少出现非零时

我在打开文件之前不知道列类型或名称

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  
read_csv('~/temp.csv', col_types = 'dDd')%>%as.tbl%>%tail(7)
以下是问题的说明:

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')

这是可行的,但是可以超过30列,而且我不会提前输入

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  
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 
data.table::fread(“~/temp.csv”)%%>%as.tbl%%>%tail(7)
#一个tibble:7x3
我要混合
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 

您可以做的一件事是读取CSV的第一行(或前n行),找出哪些列被解析为整数,并将这些列作为参数传递给
cols

library(readr)

read_csv_dbl <- function(file, ...){
  types <- sapply(suppressMessages(read_csv(file, n_max = 1)), class) 
  int_cols <- names(types[types == "integer"])
  args <- structure(replicate(length(int_cols), col_double()), names = int_cols)
  read_csv(file, col_types = do.call(cols, args), ...)
}

read_csv_dbl("~/temp.csv") %>% tail(7)
# A tibble: 7 x 3
#      i d              mix
#  <dbl> <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  

您可以尝试从
hablar
重新键入

library(hablar)
data.table::fread('~/temp.csv') %>%
  retype() %>% 
  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  
#一个tible:7 x 3
我要混合
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  
system.time(read_csv_dbl("~/temp.csv"))
#   user  system elapsed 
#   0.02    0.00    0.01 
library(hablar)
data.table::fread('~/temp.csv') %>%
  retype() %>% 
  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