I'm new to R and I'm trying to define a function in R where I call another function already in a R package (pgls and sma). I'm not sure how to do it or even if it is possible.
I have tried the following:
For pgls
getpgls <- function(P1, P2, dataf){
PGLSt <- pgls(log(P1)~log(P2), data = dataf, lambda = 'ML')
}
When I call the function:
getpgls(sym('Long'), sym('massAvg'), CompData)
I get:
Error in log(P1) : non-numeric argument to mathematical function
Something similar happens with the sma function:
getsma <- function(P1, P2, dataf){
SMAt <- sma(P1~P2,
log = "xy",
data = dataf,
)
}
when I call the function:
getsma(sym('Long'), sym('massAvg'), Data_Animal_de_pd)
I get the following error:
Error in model.frame.default(formula = P1 ~ P2, data = dataf, drop.unused.levels = TRUE) :
object is not a matrix
When I run both pgls and sma with the same argumerts, but outside the function, it runs just fine. ie.
Long.SMA <- sma(Long~massAvg,
log = "xy",
data = Data_Animal_de_pd,
)
and
Long.PGLS = pgls(log(Long)~log(massAvg), data = CompData, lambda = 'ML')
EDIT: Here I include small versions of CompData and Data_Animal_de_pd (only with 10 animals and the parameters massAvg and Long).
The class of CompData is "comparative.data" and comes from a function comparative.data which connects a phylogenetic tree with another data frame (Data_Animal_de_pd).
> dput(CompData)
structure(list(phy = structure(list(edge = structure(c(11L, 12L,
13L, 14L, 14L, 15L, 15L, 16L, 17L, 17L, 16L, 13L, 12L, 18L, 18L,
11L, 19L, 19L, 12L, 13L, 14L, 1L, 15L, 2L, 16L, 17L, 3L, 4L,
5L, 6L, 18L, 7L, 8L, 19L, 9L, 10L), dim = c(18L, 2L)), edge.length = c(100.597661,
5.254328, 4.311278, 71.0845800943, 34.327960646, 36.7566030561,
5.779375747, 15.0619109945, 15.9153248095, 15.9153245794, 30.9772360366,
75.39586827, 44.21113726, 36.439042146, 36.4390420969, 108.977279909,
72.27059073, 72.270578302), Nnode = 9L, tip.label = c("Tupaia_minor",
"Hystrix_cristata", "Geocapromys_brownii", "Myocastor_coypus",
"Hydrochoerus_hydrochaeris", "Rhinoceros_sondaicus", "Dasypus_hybridus",
"Tolypeutes_matacus", "Caluromysiops_irrupta", "Acrobates_pygmaeus"
), node.label = 11:19), class = "phylo", order = "cladewise"),
data = structure(list(massAvg = c(0.045, 20, 1.5, 7.5, 50.5,
1350, 5.5, 1.5, 0.45, 0.01), Long = c(21.565, 110.4, 55.52,
68.3266666666667, 175.2, 447.4, 47.02, 44.68, 38.58, 12.67
)), row.names = c("Tupaia_minor", "Hystrix_cristata", "Geocapromys_brownii",
"Myocastor_coypus", "Hydrochoerus_hydrochaeris", "Rhinoceros_sondaicus",
"Dasypus_hybridus", "Tolypeutes_matacus", "Caluromysiops_irrupta",
"Acrobates_pygmaeus"), class = "data.frame"), data.name = "datanm2[, c(\"massAvg\", \"Long\", \"Sci_name2\")]",
phy.name = "newphy", dropped = list(tips = character(0),
unmatched.rows = character(0))), class = "comparative.data")
Data_Animal_de_pd is a data frame that contains the information of the animals such as the length of the bones, etc.
> dput(Data_Animal_de_pd)
structure(list(massAvg = c(20, 50.5, 7.5, 1350, 0.45, 0.045,
1.5, 5.5, 1.5, 0.01), Long = c(110.4, 175.2, 68.3266666666667,
447.4, 38.58, 21.565, 55.52, 47.02, 44.68, 12.67), Sci_name = c("Hystrix cristata",
"Hydrochoerus hydrochaeris", "Myocastor coypus", "Rhinoceros sondaicus",
"Caluromysiops irrupta", "Tupaia minor", "Geocapromys brownii",
"Dasypus hybridus", "Tolypeutes matacus", "Acrobates pygmaeus"
), Sci_name2 = c("Hystrix_cristata", "Hydrochoerus_hydrochaeris",
"Myocastor_coypus", "Rhinoceros_sondaicus", "Caluromysiops_irrupta",
"Tupaia_minor", "Geocapromys_brownii", "Dasypus_hybridus", "Tolypeutes_matacus",
"Acrobates_pygmaeus")), row.names = c("10137", "10149", "10157",
"102233", "126286", "143289", "1543402", "1756220", "183749",
"190720"), class = "data.frame")```
CodePudding user response:
To make your function work with symbols (i assume from rlang::sym) you must inject them with rlang::inject:
getsma <- function(P1, P2, dataf){
SMAt <- rlang::inject(sma(!!P1 ~ !!P2,
log = "xy",
data = dataf,
))
}
but you can instead substitute and inject arguments:
getsma <- function(P1, P2, dataf){
P1 <- rlang::enexpr(P1)
P2 <- rlang::enexpr(P2)
SMAt <- rlang::inject(sma(!!P1 ~ !!P2,
log = "xy",
data = dataf,
))
}
Then call them directly:
getsma(Long, massAvg, Data_Animal_de_pd)