Stata 在Mata中使用put_formula()导出相对Excel引用

Stata 在Mata中使用put_formula()导出相对Excel引用,stata,Stata,我正在将大量字符串从Stata导出到Excel 对于一列3000+行,每个行中有不同的字符串,我需要检查每个字符串/单元格的长度。我可以在Stata中使用length()函数来完成这项工作,但我需要能够打开Excel文件,编辑给定字符串,并在Excel中自动更新长度 使用putexcel命令或mata的put\u formula()函数似乎应该很简单,但运行时间太长 从根本上说,我的问题是在mata中同时构建许多相对引用(例如,=LEN(A1)),而不是一次构建一个 看到下面的代码后,这可能更有

我正在将大量字符串从Stata导出到Excel

对于一列
3000+
行,每个行中有不同的字符串,我需要检查每个字符串/单元格的长度。我可以在Stata中使用
length()
函数来完成这项工作,但我需要能够打开Excel文件,编辑给定字符串,并在Excel中自动更新长度

使用
putexcel
命令或mata的
put\u formula()
函数似乎应该很简单,但运行时间太长

从根本上说,我的问题是在
mata
中同时构建许多相对引用(例如,
=LEN(A1)
),而不是一次构建一个

看到下面的代码后,这可能更有意义:

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);

有没有一种有效的方法可以使用
mata
和相关引用编写整个列或行的Excel公式?
mata
函数
put\u formula()
只接受行和列的标量。注意,您还需要在其字符串矩阵参数中使用复合双引号

mata中循环总是比在Stata中循环快:

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

这样,矩阵
J[3000,1]
在电子表格的单元格
B1
中写入一次。因为它有
3000
行,所以它自然会扩展到所有单元格,一直延伸到
B3000
这个答案是次要的,但可能对某些人有用

问题中代码的低效性——通过numlist循环并在mata中一次编写一个单元格中的公式——部分来自使用Stata循环(正如Pearly Spencer指出并更正的那样)。但更大的问题是,当示例从4个单元扩展到数千个单元时,mata必须写入单个单元的次数

如果可以避免循环和单独写入多个单元格,那么在大多数应用程序中,使用-putexcel-或mata的b.put_公式在速度上并没有显著差异。如果您在单个列、行或单元格矩阵中写入单元格,并且可以一次写入所有单元格,则任何一个选项都会很快。A-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)) "')
对于单个列中的30000个单元格,putexcel花费了37秒

在mata中使用Pearly Spencer的J矩阵方法耗时36秒


重要的一点是:如果要为多个单元格编写公式,请尝试将其合并为可以作为矩阵一起编写的块,而不是在所有单元格上循环。这将给你最大的速度增益;使用mata而不是-putexcel-会有所帮助,但只会提供二级改进。即使在mata中,单独写入数千个单元格也需要很长的时间。

确认,这真的很快。现在好多了,但有几点我仍然不同意。1) 我对循环的回答是指
mata
与Stata中循环的比较;不是为了比较循环和第二种
mata
方法。2)
putexcel
依赖于相同的
mata
函数,这就是为什么几乎没有区别。但是直接使用该函数可以将其作为编译的
mata
中更广泛的代码块的一部分。因此,“二阶改进”论点是不正确的,因为
putexcel
put\u formula()
满足了两种不同的需求。
*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)) "')