R: Как читать и переставлять несколько файлов - PullRequest
0 голосов
/ 09 июля 2019

Итак, я хочу прочитать несколько файлов в одну таблицу или фрейм данных. Все мои файлы выглядят как показано ниже. Для одного идентификатора может быть несколько файлов с разными измерениями

File_name:test01.csv
ID:1243
View:d
Unit:mm
length:555

File_name:test02.csv
ID:1243
View:v
Unit:mm
volume:111
width:333

File_name:  test03.csv
ID:1235
View:l
Unit:mm
length:666
height:444
width:222

В конце концов, я хочу что-то вроде этого

ID, Unit, Value,    Measure,    
1243,   mm, 555,    length
1243,   mm, 111,    volume
1243,   mm, 333,    width
1235,   mm, 666,    length  
1235,   mm, 444,    height
1235,   mm, 222,    width

До сих пор я пробовал, чтобы я составил список файлов и прочитал все файлы в одну таблицу

    csv_list %>%
  map_df(~ read.table(.,skip = 1, sep = ':')) -> data

или

    data_csv = ldply(xls_list, read.table, sep = ':', fill = T, header = F, skip = 1)

Я получаю длинную таблицу с одним файлом за другим, но я не уверен, как его переставить.

ID       :  1243
View     :  d
Unit     :  mm
length   :  555
ID       :  1243
View     :  v
Unit     :  mm
volume   :  111
width    :  333
ID       :  1235
View     :  l
Unit     :  mm
length   :  666
height   :  444
width    :  222

Другая идея, которую я возглавил, состояла в том, чтобы просто прочитать каждый файл отдельно с циклом, но это занимает очень много времени

#Complete Code
path = "D:/Scripts/R_projects/Pictures"
setwd(path)
xls_list = list.files(path, pattern = ".csv", full.names = T)

data_csv = ldply(xls_list, read.table, sep = ':', fill = T, header = F, skip = 1)

#or

xls_list %>%
  map_df(~ read.table(.,skip = 1, sep = ':')) -> data
glimpse(data)

1 Ответ

0 голосов
/ 09 июля 2019

Вы, вероятно, хотите что-то вроде следующего, где я использую readr read_delim в map_df для чтения и объединения файлов, а затем tidyr spread для преобразования данных в нечто, что имеет смысл:

library(tidyverse)

map_df(list.files(pattern = "csv$"),
       read_delim,
       delim = ":",
       col_names = F,
       trim_ws = T,
       .id = "df" # <- necessary for spread
       ) %>%
    spread(X1, X2, convert = T) # <- spread and coerce

Что возвращает:

# A tibble: 3 x 9
  df    File_name  height    ID length Unit  View  volume width
  <chr> <chr>       <int> <int>  <int> <chr> <chr>  <int> <int>
1 1     test01.csv     NA  1243    555 mm    d         NA    NA
2 2     test02.csv     NA  1243     NA mm    v        111   333
3 3     test03.csv    444  1235    666 mm    l         NA   222

Если вам это нужно в формате tidy (long), просто добавьте gather:

map_df(list.files(pattern = "csv$"),
       read_delim,
       delim = ":",
       col_names = F,
       trim_ws = T,
       .id = "df"
       ) %>%
    spread(X1, X2, convert = T) %>% 
    gather(measure_name, measure_val, height, length, volume, width)

Что возвращает:

# A tibble: 12 x 7
   df    File_name     ID Unit  View  measure_name measure_val
   <chr> <chr>      <int> <chr> <chr> <chr>              <int>
 1 1     test01.csv  1243 mm    d     height                NA
 2 2     test02.csv  1243 mm    v     height                NA
 3 3     test03.csv  1235 mm    l     height               444
 4 1     test01.csv  1243 mm    d     length               555
 5 2     test02.csv  1243 mm    v     length                NA
 6 3     test03.csv  1235 mm    l     length               666
 7 1     test01.csv  1243 mm    d     volume                NA
 8 2     test02.csv  1243 mm    v     volume               111
 9 3     test03.csv  1235 mm    l     volume                NA
10 1     test01.csv  1243 mm    d     width                 NA
11 2     test02.csv  1243 mm    v     width                333
12 3     test03.csv  1235 mm    l     width                222
...