Home > database >  Apply a vector of formulas to variables in dataframe
Apply a vector of formulas to variables in dataframe

Time:05-04

I have hundreds of formulas stored in a vector, and need apply those formulas to tree variables (called dbh and ht) in a dataframe. The situation can be reproduced as follows:

vec_formulas = c('0.32*dbh^1.22*ht^0.99',
                 '0.44   3.55*log(dbh)   log(ht)^1.03',
                 '0.40*dbh^1.30   ht*1.12')  # wrote only 3, but there are many

set.seed(123)
df_trees = data.frame(tree = 1:200,
                dbh = rnorm(200, mean=30),
                ht = rnorm(200, mean=15))

I need some result that apply every formula to every tree. If necessary, I can transform 'vec_formulas' into dataframe or datatable.

Thanks in advance!

-H.

CodePudding user response:

I think this does what you want although it does not use dplyr. I'm just applying it to the first 10 rows of df_trees. Just change "df_trees[1:10, ]" to "df_trees" to run it on all 200:

results <- matrix(nrow=nrow(df_trees[1:10, ]), ncol=length(vec_formulas))
for (i in seq(vec_formulas)) {
    for (j in seq(nrow(df_trees[1:10, ]))) {
        dbh <- df_trees[j, 2]
        ht <- df_trees[j, 3]
        results[j, i] <- eval(str2expression(vec_formulas[i]))
    }
}
results
#           [,1]     [,2]     [,3]
#  [1,] 331.4278 15.38278 51.74671
#  [2,] 318.8233 15.36617 51.22853
#  [3,] 309.5550 15.46535 52.05921
#  [4,] 307.6852 15.35055 50.80042
#  [5,] 289.6031 15.29000 49.81286
#  [6,] 307.0097 15.46758 52.05195
#  [7,] 286.0400 15.30129 49.87349
#  [8,] 269.9915 15.10859 47.61103
#  [9,] 319.2932 15.33311 50.95189
# [10,] 289.7923 15.24750 49.38832

CodePudding user response:

Using data.table:

library(data.table)
expr   <- str2expression(vec_formulas)
result <- setDT(df_trees)[, lapply(expr, \(x) eval(x)), by=.(tree, dbh, ht)]
head(result)
##    tree      dbh       ht       V1       V2       V3
## 1:    1 29.43952 17.19881 331.4278 15.38278 51.74671
## 2:    2 29.76982 16.31241 318.8233 15.36617 51.22853
## 3:    3 31.55871 14.73485 309.5550 15.46535 52.05921
## 4:    4 30.07051 15.54319 307.6852 15.35055 50.80042
## 5:    5 30.12929 14.58566 289.6031 15.29000 49.81286
## 6:    6 31.71506 14.52375 307.0097 15.46758 52.05195
  • Related