Создайте цикл для выходного файла CSV R

#r #loops #csv

#r #циклы #csv

Вопрос:

Я пытаюсь создать цикл в своем скрипте, чтобы получить выходной файл. В моем скрипте у меня уже есть другие 2 цикла для чтения входных файлов. В конце моего скрипта у меня есть df в моей среде, который я хотел бы сохранить как .csv с именем входных файлов. Вот упрощенная версия моих кодов:

     filePdbs <- Sys.glob("*.pdb")
    fileTurns <- Sys.glob("*.txt")
    for (filePdb in filePdbs) {
      "pdb" <- print(read.pdb(filePdb))
       
    ##other stuff here 
      
      "coord" <- print(read.pdb(filePdb)) 

    ##other stuff here 

      for (fileTurn in fileTurns) {
      "turn" <- read.delim(fileTurn, header = T, sep = "")

  ## here I have lines for merging info from pdb and txt and I obtain my df that I'd like to save as csv
    
      }
    }
  

Для этих 2 циклов ввода файлов я должен создать третий глобальный цикл для вывода csv с тем же именем входного файла.
Входные файлы представляют собой что-то вроде «1abc_A.pdb» и «1abc_A.txt «, я бы хотел иметь в качестве выходных данных «1abc_A.csv».
Как я могу это сделать?

Комментарии:

1. Сначала вам нужно исправить основную ошибку, заключающуюся в том, что назначения внутри этих циклов не индексируются. Вы перезаписываете результаты своих усилий по вводу.

2. Кроме того, почему ваши возвращенные объекты заключены в кавычки, например, «turn» <- . . . «? Кроме того, вы читаете цикл при fileTurns каждом filePdb чтении. Это кажется пустой тратой времени. Если файлы не являются гигантскими, было бы более эффективно считывать все файлы каждого типа в список, а затем использовать цикл для обработки списка.

3. Мне нужно выполнить мой скрипт для 1072 файлов pdb и 1072 файлов txt, которые у меня есть в той же папке

4. Кроме того, я объединяю информацию, которая у меня есть как в pdb, так и в txt, поэтому мне нужно читать их одновременно. Но я новичок в R, поэтому, если есть лучший способ сделать это, пожалуйста, дайте мне знать

Ответ №1:

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

Самым простым способом было бы использовать sub(pattern="pdb$", replacement="csv", x=filePdb) . Это находит буквы ‘pdb’ в конце строк ($ означает конец строки) и заменяет их на ‘csv’. Я бы поместил эту строку во второй вид сразу после изменения ваших переменных. В качестве альтернативы вы можете использовать filePdbs вместо filePdb и сохранить все измененные имена файлов, прежде чем использовать их.

Итак, вот что я бы изменил в вашем примере кода:

При чтении файлов, которые вам не нужны print , которые в большинстве случаев выводят содержимое в консоль, но мы хотим сохранить содержимое файла в переменной.

Переменные не заключаются в кавычки. Заключение имени в кавычки изменяет значение, и вы получаете символьную строку, в которой вы не можете ничего хранить.

Кажется, вы дважды читаете файл filePdb в цикле. Это неэффективно. Если вы хотите получить доступ к матрице с координатами, чтобы сохранить ее в переменной с именем ‘coord’, вы можете получить матрицу с pdb$xyz помощью (мы ведь говорим здесь о пакете bio3d, верно?).

Итак, затем вы просматриваете каждый файл .txt для каждого файла .pdb. ([нет текста] * [нет pdb]). Я думаю, что у вас могут быть пары файлов, и если это так, вам нужно открыть только 1 текстовый файл на pdb-файл. Вы могли бы достичь этого с помощью

 for (i in seq(along=filePdbs)) {
    pdb <- read.pdb(filePdbs[i])
    turn <- read.delim(fileTurn[i], header = T, sep = "")
    # ...
}
  

(Убедитесь sep , что аргумент соответствует вашей цели.)

Наконец, как упоминалось выше, поместите write.csv() (или для большего контроля параметров вывода write.table() ) внутри вашего внутреннего цикла и измените имя с sub() помощью .

 filePdbs <- Sys.glob("*.pdb")
fileTurns <- Sys.glob("*.txt")

for (filePdb in filePdbs) {
    pdb <- read.pdb(filePdb)
       
    ##other stuff here 
      
    coord <- pdb$xyz

    ##other stuff here 

    for (fileTurn in fileTurns) {
        turn <- read.delim(fileTurn, header = T, sep = "")

        ## here I have lines for merging info from pdb and txt and I obtain my df that I'd like to save as csv
    
        write.csv(result,
                  file=sub("pdb$", "csv", x=filePdb),
                  row.names=F)
    
    }
}
  

Комментарии:

1. Прежде всего, большое спасибо!!! и да, это пакет bio3d. Я собираюсь изменить свою ошибку, но в отношении координат она немного отличается, потому что мне нужны координаты не для всех атомов, а только для тех, которые я выбрал, поэтому мне нужно прочитать все файлы pdb, затем выбрать только то, что меня интересует, и в конце получить координаты. В любом случае я попробовал ваше решение, и оно работает! Спасибо!

2. Я проверял выходные файлы и получил все файлы csv, но, открыв их, все они представляют собой один и тот же файл с другим именем. Содержимое файлов одинаковое, последнее, что R прочитал

3. У меня есть список файлов с разными именами, но с одинаковым содержимым

4. кроме того, запуск скрипта для 8 файлов (всегда с ошибкой о содержимом) проходит без проблем, вместо запуска скрипта для 1072 файлов происходит сбой. Похоже, что у R недостаточно времени для одновременного выполнения и поэтому он выходит из строя. Возможно, необходимо создать третий глобальный цикл, который после выполнения циклов с pdb и txt записывает csv. Итак, открываем его в начале и закрываем в конце всего скрипта. Таким образом, возможно, также можно избежать ошибки о содержимом

5. Приятно слышать, что вы добились прогресса. Итак, проблема с именем файла решена, и теперь у нас есть вторая проблема с содержимым. К сожалению, мне не очень понятно, как вы хотите манипулировать данными, и поэтому, боюсь, я не могу дать вам очень эффективный совет без более подробной информации. Открытие всех файлов действительно кажется сложным для вашего сеанса R, и, как правило, вы должны стараться открывать как можно меньше файлов (но в то же время открывать файлы с наименьшей частотой — скорее всего, один раз). Наилучшая стратегия, конечно, зависит от вашей задачи.