Экспорт относительных ссылок Excel с использованием put_formula () в Mata - PullRequest
0 голосов
/ 08 февраля 2019

Я экспортирую много строк из Stata в Excel.

Для одного столбца из 3000+ строк с разными строками в каждой, мне нужно проверить длину каждой строки / ячейки.Я мог бы сделать это в Stata, используя функцию length(), но мне нужно иметь возможность открывать файл Excel, редактировать заданную строку и автоматически обновлять длину в Excel.

Кажется, что это должно быть просто с помощью команды putexcel или функции put_formula() Маты, но время запуска непомерно велико.

В корне мой вопрос касается создания множества относительных ссылок (например, =LEN(A1)) в mata одновременно, а не по одному за раз.

Это может иметь больше смысла после просмотра кода ниже:

mata: b = xl()
mata: b.create_book("Formula_Test", "Formula_Test", "xlsx")
mata: b.load_book("Formula_Test") 

*Put some strings in column 1
mata: b.put_string(1, 1, "asfas")
mata: b.put_string(2, 1, "sfhds")
mata: b.put_string(3, 1, "qwrq")
mata: b.put_string(4, 1, "dgsdgsdgsdgs")

*Formula - export one-at-a-time
    *This works, but is slow
foreach i of numlist 1/4{
    mata: b.put_formula(`i', 2, "LEN(A`i')")
}

*Formula - export all at once with relative reference
    *This would be faster, but throws error
mata: b.put_formula((1,4), 3, "LEN(INDIRECT("C[-2]",FALSE))")

Когда я запускаю последнюю строку, я получаю сообщение об ошибке:

invalid expression
r(3000);

Есть лиэффективный способ написать весь столбец или строку формул Excel, используя mata, с относительными ссылками?

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Этот ответ является второстепенным, но может быть кому-то полезен.

Неэффективность кода в вопросе - циклический просмотр списка чисел и запись формулы в одну ячейку за раз - частично исходит изиспользование цикла Stata (как указал и исправил Перли Спенсер).Но большая проблема заключается в том, сколько раз mata должна писать отдельные ячейки, когда пример расширяется с 4 ячеек до нескольких тысяч.

Если вы можете избежать зацикливания и записи множества ячеек по отдельности, используя -putexcel- или mata'sb.put_formula не сильно отличается по скорости в большинстве приложений.Если вы пишете ячейки в один столбец, строку или матрицу ячеек и можете записать их все сразу, любой из этих вариантов будет быстрым.-Putexcel- пример:

*A -putexcel- example
mata: b.create_book("Formula_Test", "Formula_Test", "xlsx")    
putexcel set "Formula_Test", sheet("Formula_Test") modify
putexcel B1:B30000 = formula(`" =LEN(INDIRECT("C[-1]",FALSE)) "')

Для 30 000 ячеек в одном столбце -putexcel- заняло 37 секунд.

Использование подхода J-матрицы Пёрли Спенсера в mata заняло 36 секунд.

Важный момент: если вы пишете формулу для многих ячеек, попробуйте объединить ее в блоки, которые можно записать вместе.как матрицы, а не зацикливание на всех ячейках.Это даст вам наибольшее увеличение скорости;Использование mata вместо -putexcel- поможет, но обеспечит только улучшение второго порядка.Даже в мате это займет много времени, чтобы написать индивидуально в тысячи ячеек.

0 голосов
/ 08 февраля 2019

Функция mata put_formula() принимает скаляры только для строк и столбцов.Обратите внимание, что вам также необходимо использовать составные двойные кавычки в аргументе строковой матрицы.

Зацикливание в mata всегда быстрее, чем в Stata:

mata:
for (i = 1; i <= 4; i++) {
    b.put_formula(i, 2, `"LEN(INDIRECT("C[-2]",FALSE))"')
}
end

Тем не менее, несмотря на ограничениенеобходимости использовать скаляры в качестве аргументов для строк и столбцов в put_formula(), цикл фактически не требуется.Это связано с тем, что в качестве конечного аргумента можно указать строковую матрицу J констант.

Действительно, в секундах то же самое делается следующим образом:

mata:
k = J(3000, 1, `"LEN(INDIRECT("C[-1]",FALSE))"')
b.put_formula(1, 2, k)
end

Таким образом, матрицаJ[3000,1] записывается один раз в ячейку B1 электронной таблицы.Поскольку он содержит 3000 строк, он естественным образом распространяется на все ячейки вплоть до B3000.

...