Читайте, транспонируйте и объединяйте фрейм данных из МНОГИХ двух фреймов данных столбцов с общей первой строкой - PullRequest
0 голосов
/ 30 ноября 2018

У меня есть тысячи TXT-файлов, разделенных запятыми, с двумя столбцами, где один столбец имеет «длину волны» для имени столбца и одинаковые значения длины волны (значения «x») для всех файлов, а другой столбец имеет имя файлав качестве имени столбца и значений ответа (различные наблюдаемые значения "y").

Если я читаю readr в одном файле, формат выглядит следующим образом:

# A tibble: 2,151 x 2
   Wavelength       a1lm_00000.asd.ref.sco.txt  ### [filename]
    <dbl>                  <dbl>
 1        350                 0.0542
 2        351                 0.0661
 3        352                 0.0686
 4        353                 0.0608
 5        354                 0.0545
 6        355                 0.0589
 7        356                 0.0644
 8        357                 0.0587
 9        358                 0.0556
10        359                 0.0519
  ...etc.

Конечный форматМне нужно:

 Filename                 "350"        "351"       "352"     "353"     etc.

a1lm_00000.asd.ref.sco.txt    0.0542       0.0661      0.0686    0.0608    etc.
a1lm_00001.asd.ref.sco.txt    0.0567       0.0680      0.0704    0.0627    etc.   
  ...etc.

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

Итак, мне нужно прочитать все эти файлы из каталога, и либо:

a.) Создайте третий столбец, который является именем файла, присвойте всем именам вторых столбцов что-то вроде «response», примените bind_rows длявсе файлы, затем используйте «распространение» в пакете tidyr.

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

Опция b.кажется предпочтительным.Любой из вариантов выглядит так, как будто мне нужно будет использовать либо lapply и, возможно, bind_rows или bind_cols.Но я не уверен, как лучше это сделать.Существует много данных, и некоторые методы, которые я использовал, заставили мою машину исчерпать память, поэтому, чем более эффективным будет использование памяти, тем лучше.

1 Ответ

0 голосов
/ 30 ноября 2018

Я рекомендую хранить все data.frame с в list.Тогда это становится простым вопросом слияния data.frame с, преобразования данных из широкого в длинный и обратно во широкий с другим ключом.

library(tidyverse)
reduce(lst, full_join) %>%
    gather(file, value, -Wavelength) %>%
    spread(Wavelength, value)
#                        file    350    351    352    353    354    355    356
#1 a1lm_00000.asd.ref.sco.txt 0.0542 0.0661 0.0686 0.0608 0.0545 0.0589 0.0644
#2 a1lm_00001.asd.ref.sco.txt 0.0542 0.0661 0.0686 0.0608 0.0545 0.0589 0.0644
#     357    358    359
#1 0.0587 0.0556 0.0519
#2 0.0587 0.0556 0.0519

Еще два комментария:

  1. Чтобы сохранить data.frame с в list, я бы сделал что-то вроде map(file_names, ~read_csv2(.x)) (или в базе R lapply(file_names, function(x) read.csv(x))).При необходимости настройте параметры file_names и read_csv2 / read.csv.
  2. В целом, я бы, вероятно, посоветовал бы против такого формата.Кажется, гораздо проще хранить данные в list длинных (и аккуратных) data.frame с.

Для полноты того же можно достичь в базе R, используя Reduce + merge для объединения данных и stack + reshape для преобразования из широкого в длинный вширокий.

df <- Reduce(merge, lst)
reshape(
    cbind(stack(df, select = -Wavelength), Wavelength = df$Wavelength),
    idvar = "ind", timevar = "Wavelength", direction = "wide")
#                          ind values.350 values.351 values.352 values.353
#1  a1lm_00000.asd.ref.sco.txt     0.0542     0.0661     0.0686     0.0608
#11 a1lm_00001.asd.ref.sco.txt     0.0542     0.0661     0.0686     0.0608
#   values.354 values.355 values.356 values.357 values.358 values.359
#1      0.0545     0.0589     0.0644     0.0587     0.0556     0.0519
#11     0.0545     0.0589     0.0644     0.0587     0.0556     0.0519

Пример данных

df1 <- read.table(text =
    "Wavelength       a1lm_00000.asd.ref.sco.txt
1        350                 0.0542
2        351                 0.0661
3        352                 0.0686
4        353                 0.0608
5        354                 0.0545
6        355                 0.0589
7        356                 0.0644
8        357                 0.0587
9        358                 0.0556
10        359                 0.0519", header = T)

df2 <- read.table(text =
    "Wavelength       a1lm_00001.asd.ref.sco.txt
1        350                 0.0542
2        351                 0.0661
3        352                 0.0686
4        353                 0.0608
5        354                 0.0545
6        355                 0.0589
7        356                 0.0644
8        357                 0.0587
9        358                 0.0556
10        359                 0.0519", header = T)

lst <- list(df1, df2)
...