将 class 列写入和读取到 csv

writing and reading class of columns to csv

对于数据框,我想将每一列(例如 char、double、factor)的数据 class 保存到 csv,然后能够读取数据和classes,回到 R.

例如,我的数据可能如下所示:

df
#> # A tibble: 3 × 3
#>    item  cost blue 
#>   <int> <int> <fct>
#> 1     1     4 1    
#> 2     2    10 1    
#> 3     3     3 0

(此处输入数据的代码:)

library(tidyverse)
df <- tibble::tribble(
  ~item, ~cost, ~blue,
     1L,    4L,    1L,
     2L,   10L,    1L,
     3L,    3L,    0L
  )

df <- df %>% 
  mutate(blue = as.factor(blue))
df

我可以这样保存 classes 数据和数据:

library(tidyverse)
classes <- map_df(df, class)

write_csv(classes, "classes.csv")
write_csv(df, "data.csv")

我可以这样读回去:

classes <- read.csv("classes.csv") %>% 
  slice(1) %>% 
  unlist()
classes
df2 <- read_csv("data.csv", col_types = classes)
df2

有没有更快的方法来完成所有这些?

特别是我保存 classes 然后读回,然后切片和取消列出的方式?

您可以使用 writeLines 及其对应的 readLines 作为 类。像这样:

classes <- sapply(df, class)
writeLines(classes, "classes.txt")
#to read them
readLines("classes.txt")

但是,还要考虑其他格式,例如 parquet(R 实现由 arrow 包提供),例如保留数据类型并由多种语言实现。

试试 csvy 包。另请参阅 http://csvy.org/ 站点。这会生成一个文件而不是两个文件来简化使用它(或者它可以选择将元数据写入一个单独的文件),也有一些其他语言的 csvy 阅读器(参见刚刚引用的 link),格式是标准化的,并且向后兼容 csv,这可能比滚动您自己的格式更好。

library(csvy)
write_csvy(df, "df.csvy")

这将生成此文件:

#---
#profile: tabular-data-package
#name: df
#fields:
#- name: item
#  type: integer
#- name: cost
#  type: integer
#- name: blue
#  type: integer
#--- 
item,cost,blue
1,4,1
2,10,1
3,3,0

可以使用:

读回
read_csvy("df.csvy")

read.csv("df.csvy", comment.char = "#")或任意数量的具有读取csv文件功能的R包。

我们可以使用以下方法将元数据提取为列表:

library(yaml)
md <- get_yaml_header("df.csvy")
md_list <- yaml.load(paste(md, collapse = "\n"))

str(md_list)
## List of 3
##  $ profile: chr "tabular-data-package"
##  $ name   : chr "df"
##  $ fields :List of 3
##   ..$ :List of 2
##   .. ..$ name: chr "item"
##   .. ..$ type: chr "integer"
##   ..$ :List of 2
##   .. ..$ name: chr "cost"
##   .. ..$ type: chr "integer"
##   ..$ :List of 2
##   .. ..$ name: chr "blue"
##   .. ..$ type: chr "integer"

已添加

data.table 包中带有参数 yaml=TRUE 的 fwrite 可用于编写 yaml headers 中内容略有不同的 csvy 文件。 rio包的导出功能也可以使用fwrite生成csvy文件。

另一种选择是使用 readr::spec_csv() 参数。

  1. 获取您想要的 csv 文件或最终数据帧并将其传递给 spec_csv(),这将生成一个 cols class 来提供该列名称和 col_type 个参数。

  2. 您可以将其保存为 csv,然后直接将其上传到您的 col_type 参数以备将来使用