Jason - 1 year ago 104

R Question

From

`R`

`sourceCpp`

`#include <RcppArmadillo.h>`

// [[Rcpp::depends(RcppArmadillo)]]

using namespace arma;

using namespace Rcpp;

// [[Rcpp::export]]

vec dnormLog(vec x, vec means, vec sds) {

int n = x.size();

vec res(n);

for(int i = 0; i < n; i++) {

res[i] = log(dnorm(x[i], means[i], sds[i]));

}

return res;

}

See this answer to see where I got the function from. This throws the error:

`no matching function for call to 'dnorm4'`

Which is the exact error I was hoping to prevent by using the loop, since the referenced answer mentions that

`dnorm`

`R::`

`dnorm`

`NumericVector`

`vec`

`log()`

`R::`

`dnorm`

`too few arguments to function call, expected 4, have 3; did you mean '::dnorm4'?`

Which is

`dnorm`

`R::dnorm4`

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

There are two nice teachable moments here:

- Pay attention to namespaces. If in doubt, don't go global.
- Check the headers for the actual definitions. You missed the fourth argument in the
*scalar*version`R::dnorm()`

.

Here is a repaired version, included is a second variant you may find interesting:

```
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::vec dnormLog(arma::vec x, arma::vec means, arma::vec sds) {
int n = x.size();
arma::vec res(n);
for(int i = 0; i < n; i++) {
res[i] = std::log(R::dnorm(x[i], means[i], sds[i], FALSE));
}
return res;
}
// [[Rcpp::export]]
arma::vec dnormLog2(arma::vec x, arma::vec means, arma::vec sds) {
int n = x.size();
arma::vec res(n);
for(int i = 0; i < n; i++) {
res[i] = R::dnorm(x[i], means[i], sds[i], TRUE);
}
return res;
}
/*** R
dnormLog( c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3))
dnormLog2(c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3))
*/
```

When we source this, both return the same result *because the R API allows us to ask for logarithms to be taken*.

```
R> sourceCpp("/tmp/dnorm.cpp")
R> dnormLog( c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3))
[,1]
[1,] -0.923939
[2,] -0.938939
[3,] -0.963939
R> dnormLog2(c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3))
[,1]
[1,] -0.923939
[2,] -0.938939
[3,] -0.963939
R>
```