标题是模糊的,但让我解释一下:
我有一个非矢量化函数,它输出一个15行树的体积估计表。每行是一个不同的度量单位或输入树的一部分。我有一个Tables
参数来帮助用户决定他们要寻找的单位和测量协议,但是在99%的用例场景中,单个树的体积估计的输出是一个包含多行的曲线。
为了演示,我从函数中删除了大约20个其他参数。胸径是树胸高处的直径。Vol
列是任意的
Est1 <- TreeVol(Tables = "All", DBH = 7)
Est1
# A tibble: 15 x 3
Tables DBH Vol
<chr> <dbl> <dbl>
1 1. Total_Above_Ground_Cubic_Volume 7 2
2 2. Gross_Inter_1/4inch_Vol 7 4
3 3. Net_Scribner_Vol 7 6
4 4. Gross_Merchantable_Vol 7 8
5 5. Net_Merchantable_Vol 7 10
6 6. Merchantable_Vol 7 12
7 7. Gross_SecondaryProduct_Vol 7 14
8 8. Net_SecondaryProduct_Vol 7 16
9 9. SecondaryProduct 7 18
10 10. Gross_Inter_1/4inch_Vol 7 20
11 11. Net_Inter_1/4inch_Vol 7 22
12 12. Gross_Scribner_SecondaryProduct 7 24
13 13. Net_Scribner_SecondaryProduct 7 26
14 14. Stump_Volume 7 28
15 15. Tip_Volume 7 30
用户可以这样使用Tables
参数:
Est2 <- TreeVol(Tables = "Scribner_BF", DBH = 7)
# A tibble: 3 x 3
Tables DBH Vol
<chr> <dbl> <dbl>
1 3. Net_Scribner_Vol 7 6
2 12. Gross_Scribner_SecondaryProduct 7 24
3 13. Net_Scribner_SecondaryProduct 7 26
问题出现在,我想写这个函数的矢量化版本,可以计算整个。csv的树库存数据的体积。理想情况下,我希望与单个树相关的多行输出作为一个长目录输出,每个15行默认输出由用户传递给Tables
参数的内容过滤,如下所示:
Est3 <- VectorizedTreeVol(Tables = "Scribner_BF", DBH = c(7, 21, 26))
# A tibble: 9 x 3
Tables DBH Vol
<chr> <dbl> <dbl>
1 3. Net_Scribner_Vol 7 6
2 12. Gross_Scribner_SecondaryProduct 7 24
3 13. Net_Scribner_SecondaryProduct 7 26
4 3. Net_Scribner_Vol 21 18
5 12. Gross_Scribner_SecondaryProduct 21 72
6 13. Net_Scribner_SecondaryProduct 21 76
7 3. Net_Scribner_Vol 26 8
8 12. Gross_Scribner_SecondaryProduct 26 78
9 13. Net_Scribner_SecondaryProduct 26 84
为了实现这一点,我编写了一个for()
循环,作为向量化函数的核心。我听很多人说这种方法效率很低(我也同意),但理论上它符合我想要达到的原则。在这个主题上,我没有找到一个更好的方法来应用于像我这样的矢量化函数。循环的一般设置如下:
for(i in 1:length(DBH)){
Output <- VectorizedTreeVol(Tables = Tables[[i]], DBH = DBH[[i]]) %>%
purrr::reduce(dplyr::full_join, by = NULL) %>%
SuppressWarnings()
和在非向量化输出总是单行的函数中,其各自的向量化函数的核心不需要封装在for()
循环中,看起来像这样:
Output <- OtherVectorizedFunction(Tables = Tables, DBH = DBH) %>%
purrr::reduce(dplyr::full_join, by = ColumnNames) %>% #ColumnNames is a vector with all of the output's column names
SuppressWarnings()
对reduce()
的特定调用在我使用它对项目中的其他函数进行矢量化时工作得很好,但是我对如何连接输出表的建议持开放态度。我已经被这个困境困扰了几个月了,任何关于如何实现这个for()
循环在理论上所追求的东西的帮助都是很棒的。有一个矢量化的函数输出像Est3
这样的曲线是可能的吗?如有任何反馈意见,我们将不胜感激。
给定此函数:
TreeVol <- function(DBH) {
data.frame(Tables = c("Tree_Vol", "Intercapillary_transfusion", "Woodiness"),
Vol = c(DBH^2, sqrt(DBH) + 3, sin(DBH)),
DBH)
}
我们可以把我们的DBH
参数放入purrr::map
,然后bind_rows
得到一个data.frame。
VecTreeVol <- function(DBH) {
DBH %>%
purrr::map(TreeVol) %>%
bind_rows()
}
结果
> VecTreeVol(DBH = 1:3)
Tables Vol DBH
1 Tree_Vol 1.0000000 1
2 Intercapillary_transfusion 4.0000000 1
3 Woodiness 0.8414710 1
4 Tree_Vol 4.0000000 2
5 Intercapillary_transfusion 4.4142136 2
6 Woodiness 0.9092974 2
7 Tree_Vol 9.0000000 3
8 Intercapillary_transfusion 4.7320508 3
9 Woodiness 0.1411200 3