【问题标题】:tidyverse method for reading CSV section读取 CSV 部分的 tidyverse 方法
【发布时间】:2018-04-18 18:09:10
【问题描述】:

场景:您有一个包含分段数据的 CSV 文件,例如

[汽车数据]

mpg,cyl,disp,hp,drat,wt,qsec,vs,am,gear,carb

21,6,160,110,3.9,2.62,16.46,0,1,4,4

21,6,160,110,3.9,2.875,17.02,0,1,4,4

22.8,4,108,93,3.85,2.32,18.61,1,1,4,1

21.4,6,258,110,3.08,3.215,19.44,1,0,3,1

18.7,8,360,175,3.15,3.44,17.02,0,0,3,2

18.1,6,225,105,2.76,3.46,20.22,1,0,3,1

14.3,8,360,245,3.21,3.57,15.84,0,0,3,4 ...

[其他东西]

原谅格式。我必须添加额外的新行以使块引用至少类似于预期的数据格式。我将在下面使用 mtcars 创建一个可重现的示例,并假设我们已经完成了对我们想要的行进行子集的简单操作,例如按照此处引用的激励代码:

# Import raw data:
data_raw <- readLines("test.txt")

# find separation line:
id_sep <- which(data_raw=="")

# create ranges of both data sets:
data_1_range <- 4:(id_sep-1)
data_2_range <- (id_sep+4):length(data_raw)

# using ranges and row data import it:
data_1 <- read.csv(textConnection(data_raw[data_1_range]))
data_2 <- read.csv(textConnection(data_raw[data_2_range]))

来自this post。换句话说,我们正在考虑采用的方法是一次性读取数据,作为行,找到我们想要的行,然后使用 read.csv “读取”它们以获取 data.frame。

好的,现在是 2017 年,我们想要拥抱 tidyverse 世界,使用 read_lines 代替 readLines,用 read_csv 代替 read.csv。

library(tidyverse)

write_csv(mtcars, "mtcars_local.csv")
# this creates an easily reproduced local file

data_raw <- readLines("mtcars_local.csv")
# henceforth assume we've found the desired rows and subsetted

data_df <- read.csv(textConnection(data_raw))

head(data_df)
   mpg cyl disp  hp drat    wt  qsec vs am gear carb
1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

# whoo hoo, the above is exactly the output we want (replicating
# the original post answer)

data_raw_2 <- read_lines("mtcars_local.csv")

data_df_2 <- read_csv(textConnection(data_raw_2))
#Error in read_connection_(con) : 
#  Evaluation error: can only read from a binary connection.

所以 read_csv 不喜欢像 read.csv 那样使用 textConnection。 read_csv 的文档确实说:

参数:

file: Either a path to a file, a connection, or literal data
      (either a single string or a raw vector).

所以,问题:

  1. 是否有一种简洁的 tidyverse 方法可以将 CSV 的特定分隔部分放入 tibble? (不涉及读取行和子集作为中间步骤)
  2. 或者从这样一个每行字符串的向量,你怎么能把它们变成一个小标题?

【问题讨论】:

    标签: r csv tidyverse readr


    【解决方案1】:

    我们可以创建单个数据字符串,其中行由所需的换行符分隔:

    paste0(data_raw, collapse = "\n") [1] "mpg,cyl,disp,hp,drat,wt,qsec,vs,am,gear,carb\n21,6,160,110,3.9,2.62,16.46,0,1,4,4\n21,6,160,110,...
    
    data_df_2 <- read_csv(paste0(data_raw, collapse = "\n"))
    
    head(data_df_2)
    # A tibble: 6 x 11
        mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
      <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int>
    1  21.0     6   160   110  3.90 2.620 16.46     0     1     4     4
    2  21.0     6   160   110  3.90 2.875 17.02     0     1     4     4
    3  22.8     4   108    93  3.85 2.320 18.61     1     1     4     1
    4  21.4     6   258   110  3.08 3.215 19.44     1     0     3     1
    5  18.7     8   360   175  3.15 3.440 17.02     0     0     3     2
    6  18.1     6   225   105  2.76 3.460 20.22     1     0     3     1
    

    好的,等等。在写这篇文章时,我想出了一个答案。但是使用 paste 似乎很笨拙。也许我已经被胶水包装宠坏了。但是有没有一种“更整洁”的方法可以将 CSV 中的一部分数据放入 tibble 中?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-26
      • 2010-10-01
      • 1970-01-01
      • 2015-06-02
      • 1970-01-01
      • 1970-01-01
      • 2018-04-01
      • 1970-01-01
      相关资源
      最近更新 更多