Сохраните каждый n-й файл в новую подпапку после оператора if в R - PullRequest
1 голос
/ 27 марта 2020

Прежде всего, извините, если этот вопрос уже был адресован где-то еще, но я не смог найти ответ.

В R У меня есть for loop, который сохраняет текст (writeLines) в файл в соответствии с определенным условием. Каждый 10-й записанный файл я хотел бы сохранить в новую подпапку. Таким образом, каждая подпапка будет иметь максимум 10 файлов.

Теперь я могу написать скрипт, который делает это, если все файлы должны быть записаны (см. Ниже), но я не уверен, как это сделать. Реализуйте изменение подпапки каждый раз, когда папка заполнена 10 файлами.

Следует пояснить приведенный ниже пример.

# generate random num
set.seed(15)
input <- rnorm(100, mean = 10, sd = 3)
# Write to file only if num is greater than threshold
thrshld <- 10
out_dir <- "~/R/tmp/Batch_Saving"

k <- 1
i <- 1
for (i in 1:length(input)) {

  if ( any(i == seq(from = 1, to = length(input), by = 10) ) ) {

    # Create a new subfolder everytime i is a multiple of 10
    sub_dir <- paste0(out_dir, "/Dir_Num_", k) 
    k <- k+1

  } 

  if ( input[i] > thrshld) {

    txt <- paste("The number", signif(input[i], 4), "is greater than", thrshld)

    # Create folder if it doesn't exist
    if (!dir.exists(sub_dir)) { dir.create(sub_dir, recursive = T) }

    # Write text to file
    writeLines(text = txt,
               con = paste0(sub_dir, "/file_", i, ".txt") )

  }

}

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

Batch_Saving > find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "{} : $(find "{}" -type f | wc -l)" file\(s\)' \;

./Dir_Num_4 :        6 file(s)
./Dir_Num_3 :        7 file(s)
./Dir_Num_2 :        4 file(s)
./Dir_Num_5 :        7 file(s)
./Dir_Num_10 :        4 file(s)
./Dir_Num_9 :        5 file(s)
./Dir_Num_7 :        3 file(s)
./Dir_Num_6 :        6 file(s)
./Dir_Num_1 :        6 file(s)
./Dir_Num_8 :        4 file(s)

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

Я полагаю, что это также может быть достигнуто с помощью других методов (например, apply), но ради обучения я хотел бы закодировать это в al oop.

Большое спасибо!

Ответы [ 3 ]

1 голос
/ 27 марта 2020

Попробуйте вложить k l oop для создания подкаталога в i l oop для проверки порога, как показано ниже:

for (i in 1:length(input)) {
  if (input[i] > thrshld) {
    if ( k %in% seq(from = 1, to = length(input), by = 10) ) {
      # Create a new subfolder everytime i is a multiple of 10
      sub_dir <- paste0(out_dir, "/Dir_Num_", k) 
    } 
    k <- k+1
#    
    txt <- paste("The number", signif(input[i], 4), "is greater than", thrshld)
#    
    # Create folder if it doesn't exist
    if (!dir.exists(sub_dir)) { dir.create(sub_dir, recursive = T) }
    # Write text to file
    writeLines(text = txt,
               con = paste0(sub_dir, "/file_", i, ".txt") )
  }
}

В результате получится следующее вывод

> list.files("~/R/tmp", recursive = T)
 [1] "Dir_Num_1/file_1.txt"   "Dir_Num_1/file_11.txt"  "Dir_Num_1/file_13.txt"  "Dir_Num_1/file_15.txt" 
 [5] "Dir_Num_1/file_18.txt"  "Dir_Num_1/file_2.txt"   "Dir_Num_1/file_4.txt"   "Dir_Num_1/file_5.txt"  
 [9] "Dir_Num_1/file_7.txt"   "Dir_Num_1/file_8.txt"   "Dir_Num_11/file_21.txt" "Dir_Num_11/file_22.txt"
[13] "Dir_Num_11/file_25.txt" "Dir_Num_11/file_26.txt" "Dir_Num_11/file_27.txt" "Dir_Num_11/file_29.txt"
[17] "Dir_Num_11/file_30.txt" "Dir_Num_11/file_32.txt" "Dir_Num_11/file_33.txt" "Dir_Num_11/file_34.txt"
[21] "Dir_Num_21/file_35.txt" "Dir_Num_21/file_36.txt" "Dir_Num_21/file_38.txt" "Dir_Num_21/file_41.txt"
[25] "Dir_Num_21/file_42.txt" "Dir_Num_21/file_43.txt" "Dir_Num_21/file_46.txt" "Dir_Num_21/file_48.txt"
[29] "Dir_Num_21/file_49.txt" "Dir_Num_21/file_50.txt" "Dir_Num_31/file_51.txt" "Dir_Num_31/file_52.txt"
[33] "Dir_Num_31/file_54.txt" "Dir_Num_31/file_55.txt" "Dir_Num_31/file_58.txt" "Dir_Num_31/file_59.txt"
[37] "Dir_Num_31/file_61.txt" "Dir_Num_31/file_68.txt" "Dir_Num_31/file_70.txt" "Dir_Num_31/file_75.txt"
[41] "Dir_Num_41/file_77.txt" "Dir_Num_41/file_78.txt" "Dir_Num_41/file_80.txt" "Dir_Num_41/file_81.txt"
[45] "Dir_Num_41/file_82.txt" "Dir_Num_41/file_83.txt" "Dir_Num_41/file_88.txt" "Dir_Num_41/file_89.txt"
[49] "Dir_Num_41/file_93.txt" "Dir_Num_41/file_94.txt" "Dir_Num_51/file_96.txt" "Dir_Num_51/file_98.txt"
0 голосов
/ 30 марта 2020

После ответа nurandi я добавил еще один счетчик c, который подсчитывает, сколько раз записан файл, и с помощью if-statement я проверяю, что число увеличилось на 10, и каждый раз, когда он создает новую папку пронумерованы с помощью k.

# generate random num
set.seed(15)
input <- rnorm(100, mean = 10, sd = 3)
# Write to file only if num is greater than threshold
thrshld <- 10
out_dir <- "~/R/tmp/Batch_Saving"
k <- 1
i <- 1
c <- 1
for (i in 1:length(input)) {

  if (input[i] > thrshld) {

    txt <- paste("The number", signif(input[i], 4), "is greater than", thrshld)

    if ( c %in% seq(from = 1, to = length(input), by = 10) ) {
      # Create a new subfolder everytime c is higher than a multiple of 10
      sub_dir <- paste0(out_dir, "/Dir_Num_", k) 
      k <- k + 1
    } 

    # Create folder if it doesn't exist
    if (!dir.exists(sub_dir)) { dir.create(sub_dir, recursive = T) }
    # Write text to file
    writeLines(text = txt,
               con = paste0(sub_dir, "/file_", i, ".txt") )

    # Increase wrote files counter to +1
    c <- c + 1
  }
}

, чтобы папки были пронумерованы в порядке возрастания.

sapply(list.dirs(recursive = F), function(x) length( list.files(x) ) )

./Dir_Num_1 ./Dir_Num_2 ./Dir_Num_3 ./Dir_Num_4 
         10          10          10          10 
./Dir_Num_5 ./Dir_Num_6 
         10           2 
0 голосов
/ 27 марта 2020

Попробуйте:

# generate random num
set.seed(15)
input <- rnorm(100, mean = 10, sd = 3)

# Write to file only if num is greater than threshold
thrshld <- 10
out_dir <- "~/R/tmp/Batch_Saving"

for (i in 1:length(input)) {

  # Create sub-folder if it doesn't exist
  sub_dir = paste0(out_dir, "/Dir_Num_", ceiling(i/10))
  dir.create(sub_dir, showWarnings = F)

  if ( input[i] > thrshld) {

    txt <- paste("The number", signif(input[i], 4), "is greater than", thrshld)

    # Write text to file
    writeLines(text = txt,
               con = paste0(sub_dir, "/file_", i, ".txt") )

  }

}

Количество файлов в подпапке

sapply(list.dirs(), function(x)length(list.files(x)))

#            .  ./Dir_Num_1 ./Dir_Num_10  ./Dir_Num_2  ./Dir_Num_3  ./Dir_Num_4 
#           11            6            4            4            7            6 
#  ./Dir_Num_5  ./Dir_Num_6  ./Dir_Num_7  ./Dir_Num_8  ./Dir_Num_9 
#            7            6            3            4            5 
...