我正在将很多字符串从Stata导出到Excel。
对于# A tibble: 3 x 3
# Groups: id [1]
id year value
<int> <int> <int>
1 2 1998 90
2 2 1999 91
3 2 2002 92
行中的每一列,每行中都有不同的字符串,我需要检查每个字符串/单元格的长度。我可以使用3000+
函数在Stata中做到这一点,但是我需要能够打开Excel文件,编辑给定的字符串,并在Excel中自动更新长度。
使用length()
命令或mata的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公式的列或行?
答案 0 :(得分:2)
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
的所有单元格。
答案 1 :(得分:1)
此答案是次要的,但对某人可能有用。
问题代码的效率低下–遍历一个numlist并将该公式一次写入一个单元格中–一定程度上是由于使用了Stata循环(如Pearly Spencer所指出和纠正的)。但是更大的问题是,当示例从4个单元扩展到数千个时,mata必须编写单个单元的次数。
如果可以避免单独循环和写入多个单元格,则在大多数应用程序中,使用-putexcel-或mata的b.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秒。
在mata中使用Pearly Spencer的J矩阵方法耗时36秒。
重要的一点是:如果您要向多个单元格编写公式,请尝试将其合并为可作为矩阵一起编写的块,而不是遍历所有单元格。这将使您获得最大的速度提升;使用mata代替-putexcel-会有所帮助,但只会提供二阶改进。即使在mata中,也要花很长时间才能分别写入数千个单元格。