Мне нужно прочитать файл шаблона test.txt
, изменить содержимое и затем записать на диск измененную копию с именем foo`i`.in
(i
- номер итерации). Поскольку мне нужно выполнить эту операцию много раз (миллион раз не было бы необычным), предпочтительными были бы эффективные решения. Файл шаблона выглядит так:
1
bar.out
70.000000000000000
2.000000000000000
14.850000000000000
8000.000000000000000
120.000000000000000
60.000000000000000
0.197500000000000
0.197500000000000
2.310000000000000
0.200000000000000
0.000000000000000
1.000000000000000
0.001187700000000
22.000000000000000
1.400000000000000
1.000000000000000
0.010000000000000
100
0.058600000000000
-0.217000000000000
0.078500000000000
-0.110100000000000
30
500.000000000000000
T
Мне не нужно изменять все строки, только некоторые из них. В частности, мне нужно изменить bar.out
на bar`i`.out
, где i
- индекс итерации. Мне также необходимо изменить некоторые числовые строки со следующими значениями:
parameters <- data.frame(index = c(1:10, 13:16, 21:22), variable = c("P1",
"P2", "T1", "s", "D", "L", "C1", "C2", "VA",
"pw", "m", "mw", "Cp", "Z", "ff_N", "ff_M"),
value = c(65, 4, 16.85, 7900, 110, 60, 0.1975, .1875, 2.31,
0.2, 0.0011877, 22.0, 1.4, 1.0, 0.0785, -0.1101))
Все остальные строки должны оставаться неизменными, включая последнюю строку T
. Таким образом, предполагая, что я на первой итерации, ожидаемый вывод представляет собой текстовый файл с именем foo1.in
с содержимым (точный формат номера не важен, если все значимые цифры в parameters$value
включены в foo1.in
):
1
bar1.out
65.000000000000000
4.000000000000000
16.850000000000000
7900.000000000000000
110.000000000000000
60.000000000000000
0.197500000000000
0.187500000000000
2.310000000000000
0.200000000000000
0.000000000000000
1.000000000000000
0.001187700000000
22.000000000000000
1.400000000000000
1.000000000000000
0.010000000000000
100
0.058600000000000
-0.217000000000000
0.078500000000000
-0.110100000000000
30
500.000000000000000
T
Модификация foo.in
и bar.out
проста:
template <- "test.txt"
infile <- "foo.in"
string1 <- "bar.out"
iteration <- 1
# build string1
elements <- strsplit(string1, "\\.")[[1]]
elements[1] <- paste0(elements[1], iteration)
string1 <- paste(elements, collapse = ".")
# build infile name
elements <- strsplit(infile, "\\.")[[1]]
elements[1] <- paste0(elements[1], iteration)
infile<- paste(elements, collapse = ".")
Теперь я хотел бы прочитать файл шаблона и изменить только намеченные строки. Первая проблема, с которой я сталкиваюсь, заключается в том, что read.table
выводит только кадр данных. Так как мой файл шаблона содержит числа и строки в том же столбце, если я прочитаю весь файл с помощью read.table
, я бы получил столбец символов (я думаю). Я обойду проблему, читая только числовые значения, которые меня интересуют:
# read template file
temp <- read.table(template, stringsAsFactors = FALSE, skip = 2, nrows = 23)$V1
lines_to_read <- temp[length(temp)]
# modify numerical parameter values
temp[parameters$index] <- parameters$value
Однако теперь я не знаю, как написать foo1.in
. Если я использую write.table
, я могу писать только матрицы или dataframes на диск, поэтому я не могу записать файл, который содержит числа и строки в том же столбце. Как я могу это решить?
EDIT Я предоставляю немного информации об этой проблеме, чтобы объяснить, почему мне нужно многократно писать этот файл. Итак, идея состоит в том, чтобы выполнить байесовский вывод для параметров калибровки компьютерного кода (исполняемого файла). Основная идея проста: у вас есть черный ящик (коммерческий) компьютерный код, который имитирует физическую проблему, например код FEM. Позвольте называть этот код Джо. Учитывая входной файл, Joe выводит предсказание для ответа физической системы. Теперь у меня также есть фактические экспериментальные измерения для реакции этой системы. Я хотел бы найти значения входов Joe, так что разница между выводами Joe и реальными измерениями сводится к минимуму (на самом деле все совсем по-другому, но это только для того, чтобы дать представление). На практике это означает, что мне нужно много раз запускать Joe с разными входными файлами и итеративно находить входные значения, которые уменьшают "несоответствие" между предсказанием Джо и экспериментальными результатами. Короче говоря:
- Мне нужно создать много входных (текстовых) файлов
- Я не знаю заранее содержимое входных файлов. Числовые параметры изменяются в процессе оптимизации итерационным способом.
- Мне также нужно прочитать вывод Joe для каждого входа. На самом деле это еще одна проблема, и я, вероятно, напишу конкретный вопрос по этому вопросу.
Итак, хотя Joe является коммерческим кодом, для которого у меня есть только исполняемый файл (без источника), байесовский вывод выполняется в R, потому что R (и, для чего это важно, Python) имеют отличные инструменты для выполнения такого рода исследования.