Разделите фрейм данных на основе столбца и запишите несколько разделенных TXT-файлов с указанными c именами. - PullRequest
1 голос
/ 18 февраля 2020

Я имею дело с моими огромными .txt фреймами данных, сгенерированными из микроскопических c данных. Каждый отдельный выходной файл .txt занимает от 3 до 4 ГБ! И у меня есть пара сотен из них ....

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

Вот абстрактный пример фрейма данных:

df <- read.csv("output.txt", sep="\t", skip = 9,header=TRUE, fill = T)
df

Row  Column stimulation Compound Concentration treatmentsum Pid_treatmentsum  var1 var2  var3  ...
1    1      uns         Drug1    3             uns_Drug1_3  Jack_uns_Drug1_3  15.0 20.2  3.568 ...
1    1      uns         Drug1    3             uns_Drug1_3  Jack_uns_Drug1_3  55.0 0.20  9.068
1    1      uns         Drug2    5             uns_Drug2_5  Jack_uns_Drug2_5  100  50.2  3.568
1    1      uns         Drug2    5             uns_Drug2_5  Jack_uns_Drug2_5  75.0 60.2  13.68
1    1      3S          Drug1    3             3s_Drug3_3   Jack_3s_Drug1_3   65.0 30.8  6.58
1    1      4S          Drug1    3             4s_Drug3_3   Jack_4s_Drug1_3   35.0 69.3  2.98
.....

И я хотел бы разбить фрейм данных на основе общего значения в категорическом столбце Treatum. Таким образом, я могу обработать все клетки одним и тем же лекарством и одной и той же дозировкой, иначе все "uns_Drug1_3" идет в один файл output.txt.

Я видел похожий пост, поэтому я использовал split ()

sptdf <- split(df, df$treatmentsum)

, он работал, так как теперь sptdf дал мне списки фреймов данных. Теперь я хочу записать их в виде таблиц, в идеале я хочу использовать элемент «Pid_treatmentsum» в качестве имени каждого файла разделенного файла, так как они должны иметь точно такой же «Pid_treatmentsum» после разделения. Я не совсем знаю, как это сделать, поэтому до сих пор я могу, по крайней мере, вручную ввести идентификатор пациента и присоединиться к ним, вставив

lapply(names(sptdf), function(x){write.table(sptdf[[x]], file = paste("Jack", x, sep = "_"))}) 

Это работает не в том смысле, что он записывает все отдельные файлы с правильные заголовки, но они не являются .txt, и если я открою их в Excel, я получу предупреждающие сообщения, что они повреждены. Между тем в R я получаю предупреждающие сообщения
Ошибка в файле (file, ifelse (append, "a", "w")): не удается открыть соединение

Где я понял это неправильно?

Учитывая размер микроскопа каждого выходного файла (3-4 ГБ), это лучший способ сделать это?

И если я смогу сделать еще sh, могу ли я сбросить все сотни этих огромных файлов в папке, и могу ли я написать al oop, чтобы автоматизировать процесс вместо разделения одного файла за раз? Единственная проблема, которую я предвижу, состоит в том, что файлы микроскопа всегда имеют одно и то же имя, называемое «выходные данные».

Заранее спасибо, и извините за длинный пост.

Ура, ML

1 Ответ

0 голосов
/ 18 февраля 2020

Я не верю, что это сильно отличается от кода ОП, но здесь это так.

Сначала набор тестовых данных. Я буду использовать копию встроенного набора данных iris

df <- iris
names(df)[5] <- "Pid_treatmentsum"

Теперь код записи файла.

sptdf <- split(df, df$Pid_treatmentsum)
lapply(sptdf, function(DF){
  outfile <- as.character(unique(DF[["Pid_treatmentsum"]]))
  outfile <- paste0(outfile, ".txt")
  write.table(DF, 
              file = outfile,
              row.names = FALSE,
              quote = FALSE)
})

Если Excel жалуется, что файл поврежден, возможно write.csv (и расширение файла "csv") решит проблему.

Редактировать.

Чтобы автоматизировать приведенный выше код для обработки множества файлов, split/lapply можно переписать как функцию. Затем вызывается функция, передавая имена файлов в качестве аргумента.
Что-то вроде (не проверено)

splitFun <- function(file, col = "Pid_treatmentsum", ...){
  X <- read.table(file, header = TRUE, ...)
  sptdf <- split(X, X[[col]])
  lapply(sptdf, function(DF){
    outfile <- as.character(unique(DF[[col]]))
    outfile <- paste0(outfile, ".txt")
    write.table(DF,
                file = outfile,
                row.names = FALSE,
                quote = FALSE)
  })
}


filenames <- list.files(pattern = "<a regular expression>")
lapply(filenames, splitFun)
...