метод tidyverse для чтения раздела CSV

Сценарий: у вас есть файл CSV с данными в разделах, например

[Данные об автомобиле]

миль на галлон, цил, 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
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.
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
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.
range]))

из этого сообщения. Другими словами, подход, который мы рассматриваем, состоит в том, чтобы прочитать данные за один раз в виде строк, найти нужные строки и затем «прочитать» их, используя 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 не любит использовать textConnection, как read.csv. В документации для read_csv сказано:

Аргументы:

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

Итак, вопрос (ы):

  1. Есть ли аккуратный способ превратить определенный раздел CSV в тиббл? (это не предполагает чтение строк и разбиение на подмножества в качестве промежуточного шага)
  2. Или из такого вектора строк каждой строчки как их в тибл собрать?

person doctorG    schedule 06.11.2017    source источник


Ответы (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

Ладно, и вуаля. Написав этот пост, я нашел ответ. Но использование пасты кажется бессмысленным. Может быть, я был испорчен, прочитав о упаковке клея. Но есть ли более «аккуратный» способ перенести часть данных из CSV в тиббл?

person doctorG    schedule 06.11.2017