R中一组向量和向量函数的线性组合

时间:2017-08-06 00:14:12

标签: r loops

假设我们有三个向量x1,x2,x3,并且我们还有四个向量a0,a1,a2,a3,我们称之为系数。

x1 <- rnorm(10); x2 <- rnorm(10); x3 <- rnorm(10);
a0 <- runif(25); a1 <- runif(25); a2 <- runif(25); a3 <- runif(25);

我想计算以下数据帧L0,L1,L2,L3(所有这些都有10行和25列)

L0<-data.frame(matrix(0,nrow=10,ncol=25))
L1<-data.frame(matrix(0,nrow=10,ncol=25))
L2<-data.frame(matrix(0,nrow=10,ncol=25))
L3<-data.frame(matrix(0,nrow=10,ncol=25))

for (i in 1:10){
   L0[i,] <- a0 + mean(a1)*x1[i] + mean(a2)*x2[i] + mean(a3)*x3[i]
   L1[i,] <- mean(a0) + a1*x1[i] + mean(a2)*x2[i] + mean(a3)*x3[i]
   L2[i,] <- mean(a0) + mean(a1)*x1[i] + a2*x2[i] + mean(a3)*x3[i]
   L3[i,] <- mean(a0) + mean(a1)*x1[i] + mean(a2)*x2[i] + a3*x3[i] 
 }

我想知道如何在计算相应的L时将系数a用作向量,但在该计算中保留系数的其余部分作为这些系数的函数({{1在这个例子中)。 R 是否有更好的方法来执行上一个代码的操作?即,通过向量集mean计算每个L,以便在a的计算中,系数L0与其所有元素一起使用,但其他元素a0 1}},a1a2是他们的对应手段;在a3的计算中,系数L1与其所有元素一起使用,但其他a1a0a2是其对应的均值,因此上。

2 个答案:

答案 0 :(得分:3)

考虑一种嵌套的lapplymapply方法,最终创建一个数据框列表,如图所示,每个元素都等同于原始的L's。下面演示了两个版本。

更长的版本 (使用if逻辑)

alternative_means_sums <- function(a,b,c,d) {  
  if (d == 1) {
    vec <- a0 + mean(a1)*a + mean(a2)*b + mean(a3)*c
  }
  if (d == 2) {
    vec <- mean(a0) + a1*a + mean(a2)*b + mean(a3)*c
  }
  if (d == 3) {
    vec <- mean(a0) + mean(a1)*a + a2*b + mean(a3)*c
  }
  if (d == 4) {
    vec <-mean(a0) + mean(a1)*a + mean(a2)*b + a3*c
  }
  return(vec)
}

dfList <- lapply(seq(4), function(i)
  data.frame(t(mapply(alternative_means_sums, x1, x2, x3, i))))

all.equal(dfList[[1]], L0)
# [1] TRUE
all.equal(dfList[[2]], L1)
# [1] TRUE
all.equal(dfList[[3]], L2)
# [1] TRUE
all.equal(dfList[[4]], L3)
# [1] TRUE

缩短版本 (收集列表中的所有资料,然后按位置删除不需要的平均值并添加非平均因子)

a_list <- list(a0, a1, a2, a3)      # OR:   mget(ls(pattern="^a[0-9]$"))

alternative_means_sums <- function(a,b,c,d) { 
  args <- list(1,a,b,c)
  tmp <- c(mean(a0), mean(a1)*a, mean(a2)*b, mean(a3)*c)[-d]      
  vec <- sum(tmp) + a_list[[d]]*args[[d]]

  return(vec)
}

dfList2 <- lapply(seq(4), function(i)
  data.frame(t(mapply(alternative_means_sums, x1, x2, x3, i))))

all.equal(dfList2[[1]], L0)
# [1] TRUE
all.equal(dfList2[[2]], L1)
# [1] TRUE
all.equal(dfList2[[3]], L2)
# [1] TRUE
all.equal(dfList2[[4]], L3)
# [1] TRUE

答案 1 :(得分:2)

这是使用dplyr包的方法。首先,一些设置:

library(dplyr)
A <- data.frame(a0, a1, a2, a3)
X <- cbind(1, x1, x2, x3)

现在我们创建一个函数来创建L数据帧。

L <- function(i, mat = A, fun = mean) {
  if (i + 1 > ncol(mat)) 
    stop("i must be less than or equal to number of 'a' vectors")
  out <- mutate_at(mat, seq(ncol(mat))[-(i + 1)], fun)
  out <- as.data.frame(X %*% t(as.matrix(out)))
  colnames(out) <- paste0("X", seq(nrow(mat)))
  out
}

mutate_at函数将A数据框中每列中的值转换为列均值,但i中指示的列除外。然后我们使用矩阵乘法来获得所需的输出。最后一步以X1, X2, ..., X25格式重命名输出中的列,以匹配原始L0, L1等数据帧。

所以我们有

all.equal(L(0), L0)
[1] TRUE

我们也可以

out <- lapply(0:3, L)
all.equal(out[[1]], L0)
# [1] TRUE
all.equal(out[[2]], L1)
# [1] TRUE

等等。