Как применить функцию внутри цикла for для набора существующих переменных предопределенной структуры в R?

r

41 просмотра

1 ответ

У меня есть функция, для которой мне нужны матрица и вектор в качестве аргументов. Я извлеку матрицы и векторы из а data.matrix()и data.frame()соответственно.

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 )) }

Теперь я хочу применить результирующие переменные к функции cor2cov()(функция вставляется под разделителем в разделе кода в конце этого поста, где вы также можете найти вход для создания минимального воспроизводимого примера).

Например: cor2cov(cor1,vavc1)

Я попытался включить следующий код в цикл for

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

Который дает мне ошибку:

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

По сути, функция не получает правильных аргументов.

Любая помощь приветствуется.


Код функции и минимальный теперь следует:

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.
Автор: Feal Источник Размещён: 08.11.2019 11:12

Ответы (1)


0 плюса

Решение

Я думаю, что вы хотите использовать get(...)вместо того, noquote(...)чтобы динамически ссылаться на переменные:

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

get()Функция принимает строку и возвращает переменную / функцию R с таким именем , если он существует. По умолчанию это поиск в глобальном пространстве имен.

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

В то время как noquote()функция с другой стороны возвращает строку:

> noquote('ls')
[1] ls
> class(noquote('ls'))
[1] "noquote"
> noquote('ls') == 'ls'
Автор: Keith Hughitt Размещён: 20.08.2016 11:14
Вопросы из категории :
32x32