Feal - 1 year ago 69
R Question

# How to apply a function within a for loop for a set of existing variables of a predifined structure in R?

I have a function for which i need a matrix and a vector as arguments. I will extract the matrices and vectors from a

`data.matrix()`
and
`data.frame()`
respectively.

```for (i in 1:3) { assign(paste("vavc", i, sep = ""),as.numeric(inputvar[i,-1])); assign(paste("cor", i, sep = ""),matrix(input[which(ArtID ==i),-1],nrow = 2 )) }```

What I want now is to apply the resulting variables to the function
`cor2cov()`
(the function is pasted below the divider in the code section at the end of this post, where you can also find the input for creating a minimum reproducible example).

For example:
`cor2cov(cor1,vavc1)`

I tried to incorporate the following code into the for-loop

`cor2cov(noquote(paste("cor", i, sep = "")),noquote(paste("vavc", i, sep = "")))`

Wich gives me an error:

```#Error in cor2cov(noquote(paste("cor", 1, sep = "")), noquote(paste("vavc", : 'corMat must be a matrix```

Basically the function doesn't get the right arguments.

Any help is appreciated.

Function and minimum code follows now:

``````ArtID = c(1,2,3)
AC_AC = c(1,1,1)
MKT_AC = c(0.5,0.6,0.2)
AC_MKT = c(0.5,0.6,0.2)
MKT_MKT = c(1,1,1)
input = data.frame(ArtID, AC_AC, MKT_AC, AC_MKT, MKT_MKT)
input <- data.matrix(input)
#Now we need to create the variance vectors
#Create data.frame for testing the varvector-creation loop

ArtIDv = c(1,2,3)
Varvec1 = c(0.3, 0.6)
Varvec1 = c(0.3, 0.6, 0.35)
Varvec2 = c(0.15, 0.19, 0.21)
inputvar = data.frame(ArtIDv,Varvec1,Varvec2)

for (i in 1:3) {
assign(paste("vavc", i, sep = ""),as.numeric(inputvar[i,-1]));
assign(paste("cor", i, sep = ""),matrix(input[which(ArtID ==i),-1],nrow = 2 ))
}

-------------------------

2) Incorporate the cor2cov()-Function into R by copy-pasting the following code:

# Goal: convert a correlation matrix and variance vector
#       into the corresponding covariance matrix
#
# Input:
#   'corMat' is a square matrix with 1's on the diagonal
#      and valid correlations on the off-diagonal
#   'varVec' is a valid variance vector, with length
#      matching the dimension of 'covMat'.  A single
#      row or single column matrix is also allowed.
# Output:
#   the covariance matrix
#
# A warning is given if the covariance matrix is not
#   positive definite.
#
cor2cov = function(corMat, varVec) {
# test the input
if (!is.matrix(corMat)) stop("'corMat must be a matrix")
n = nrow(corMat)
if (ncol(corMat) != n) stop("'corMat' must be square")
if (mode(corMat) != "numeric") stop("'corMat must be numeric")
if (mode(varVec) != "numeric") stop("'varVec must be numeric")
if (!is.null(dim(varVec))) {
if (length(dim(varVec)) != 2) stop("'varVec' should be a vector")
if (any(dim(varVec)==1)) stop("'varVec' cannot be a matrix")
varVec = as.numeric(varVec) # convert row or col matrix to a vector
}
if (!all(diag(corMat) == 1)) stop("correlation matrices have 1 on the diagonal")
if (any(corMat < -1 | corMat > +1))
stop("correlations must be between -1 and 1")
if (any(varVec <= 0)) stop("variances must be non-negative")
if (length(varVec) != n) stop("length of 'varMat' does not match 'corMat' size")

# Compute the covariance
sdMat = diag(sqrt(varVec))
rtn = sdMat %*% corMat %*% t(sdMat)
if (det(rtn)<=0) warning("covariance matrix is not positive definite")
return(rtn)
}

#The cor2cov-Function will now be available in your global environment.
``````

Answer Source

I think you want to use `get(...)` instead of `noquote(...)` to refer to the variables dynamically:

``````> cor2cov(get(paste("cor", i, sep = "")), get(paste("vavc", i, sep = "")))
[,1]       [,2]
[1,] 0.35000000 0.05422177
[2,] 0.05422177 0.21000000
``````

The `get()` function takes a string and returns an R variable/function with that name if it exists. It defaults to searching the global namespace.

``````> x = 'ls'
> class(ls)
[1] "function"
> class(get('ls'))
[1] "function"
``````

While the `noquote()` function on the other hand returns a string:

``````> noquote('ls')
[1] ls
> class(noquote('ls'))
[1] "noquote"
> noquote('ls') == 'ls'
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download