R:如何在两个列表上运行函数? [英] R: How to run function on two lists?

查看:130
本文介绍了R:如何在两个列表上运行函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 函数(Z,p){
imp < - as.vector(cbind(imp = rowSums(Z)))
exp < - as.vector(t(cbind(exp = colSums(Z))))
x = p + imp
ac = p + imp - exp
einsdurchx = 1 / as.vector(x)
einsdurchx [is.infinite(einsdurchx)] < - 0
A = Z% *%diag(einsdurchx)
R = solve(diag(length(p)) - A)%*%diag(p)
C = ac * einsdurchx
R_bar = diag(as。向量(C))%*%R
rR_bar = round(R_bar)
return(rR_bar)
}

矩阵和一个向量上工作正常。不过,我需要在矩阵列表矢量列表中运行此函数。我尝试了 lapply / mapply 以下这个示例,请参阅下文。这里有一些示例数据显示了我的数据结构:

  Z < -  list(111.2012= matrix(c(0 ,0,100,200,0,0,0,0,50,350,0,50,50,200,200,0),
nrow = 4,ncol = 4,byrow = T),
112.2012=矩阵(c (10,90,0,30,10,90,0,10,200,50,10,350,150,100,200,10),
nrow = 4,ncol = 4,byrow = T))
p < - list( 111.2012= c(200,1000,100,10),112.2012= c(300,900,50,100))

这里我试过的 lapply 代码(我改变了X和Y函数中的所有Z和p,不知道是否需要) :

  lapply(X = Z,Y = p,函数(Z,p){
imp < - > as.vector(cbind(imp = rowSums(X)))
exp < - as.vector(t(cbind(exp = colSums(X))))
x = Y + imp
ac = Y + imp - exp
einsdurchx = 1 / as.vector(x)
einsdurchx [is.infinite(einsdurchx)] < - 0
A = X%*%diag (einsdurchx)
R = solve(diag(length(Y)) - A)%*% diag(Y)
C = ac * einsdurchx
R_bar = diag(as.vector(C))%*%R
rR_bar = round(R_bar)
return(rR_bar)
})

我似乎有一个索引列表对象的问题,但是对于列表来说我相对较新。你有什么想法我做错了吗?此外,对象(Z和p)需要按名称匹配,因为列表中有超过1000个对象(Info:两个列表具有相同的对象/项目长度,并且Z中矩阵的行/列具有与p中的矢量长度相同)。



这里我预期的结果:

  $'112.2012'
[,1] [,2] [,3] [,4]
[1,] 174 191 31 4
[2,] 0 450 0 0
[3,] 11 188 49 1
[4,] 14 171 20 5

$'111.2012'
[,1] [,2] [,3] [,4]
[1,] 45 14 0 1
[2,] 8 670 0 2
[3,] 190 157 44 59
[4,] 57 59 6 38

我非常感谢您的想法。

解决方案

您可以使用 mapply ,这是 lapply 的多变量版本, / b>

  fun < - 函数(Z,p){
imp < - as.vector(cbind(imp = rowSums(Z)))
exp< - as.vector(t(cbind(exp = colSums(Z))))
x = p + imp
ac = p + imp - exp
einsdurchx = 1 / as.vector(x)
einsdurchx [is.infinite(einsdurchx)] < - 0
A = Z%*%diag(einsdurchx)
R = solve(diag(length(p )) - A)%*%diag(p)
C = ac * einsdurchx
R_bar = diag(as.vector(C))%*%R
rR_bar = round(R_bar)
return(rR_bar)
}

Z < - list(111.2012= matrix(c(0,0,100,200,0,0,0,0,50,350,0) ,50,50,200,200,0),
nrow = 4,ncol = 4,byrow = T),
112.2012=矩阵(c(10,90,0,30,10,90,0) ,10,200,50,10,350,150,100,200,10),
nrow = 4,ncol = 4,byrow = T))
p < - list(111.2012= c(200,1000,100,10) ,
112.2012= c(300,900,50,100))


mapply(fun,Z,p,SIMPLIFY = FALSE)
## $`111.2012`
## [,1] [,2] [,3] [,4]
## [1,] 174 191 31 4
## [2,] 0 450 0 0
## [3,] 11 188 49 1
## [4,] 14 171 20 5

## $`112.2012`
## [,1] [,2] [,3] [,4]
## [1,] 45 14 0 1
## [2,] 8 670 0 2
## [3,] 190 157 44 59
## [4,] 57 59 6 38


I want to run the following function on two lists:

function(Z, p) {
  imp <- as.vector(cbind(imp=rowSums(Z)))
  exp <- as.vector(t(cbind(exp=colSums(Z))))
  x = p + imp
  ac = p + imp - exp  
  einsdurchx = 1/as.vector(x)    
  einsdurchx[is.infinite(einsdurchx)] <- 0
  A = Z %*% diag(einsdurchx)
  R = solve(diag(length(p))-A) %*% diag(p)
  C = ac * einsdurchx
  R_bar = diag(as.vector(C)) %*% R
  rR_bar = round(R_bar)
  return(rR_bar)
}

which works fine on a matrix and a vector. However, I need to run this function on a list of matrices and a list of vectors. I tried so far lapply/mapply following this example, see below. Here some example data showing the structure of my data:

Z <- list("111.2012"= matrix(c(0,0,100,200,0,0,0,0,50,350,0,50,50,200,200,0),
                             nrow = 4, ncol = 4, byrow = T),
           "112.2012"= matrix(c(10,90,0,30,10,90,0,10,200,50,10,350,150,100,200,10),
                              nrow = 4, ncol = 4, byrow = T))
p <- list("111.2012"=c(200, 1000, 100, 10), "112.2012"=c(300, 900, 50, 100))

Here the lapply code I tried (I changed all Z and p in the function for X and Y, don't know if needed):

lapply(X=Z, Y=p, function(Z, p) {
  imp <- as.vector(cbind(imp=rowSums(X)))
  exp <- as.vector(t(cbind(exp=colSums(X))))
  x = Y + imp
  ac = Y + imp - exp  
  einsdurchx = 1/as.vector(x)    
  einsdurchx[is.infinite(einsdurchx)] <- 0
  A = X %*% diag(einsdurchx)
  R = solve(diag(length(Y))-A) %*% diag(Y)
  C = ac * einsdurchx
  R_bar = diag(as.vector(C)) %*% R
  rR_bar = round(R_bar)
  return(rR_bar)
} )

I seems that I have a problem indexing the the objects of the list, but I am relatively new with lists. Do you have any ideas what I'm doing wrong? Further the objects (of Z and p) need to be matched by name, as I have more than 1000 objects in the lists (Info: both lists have the same object/item length, and rows/cols of the matrices in Z have the same length as the vectors in p).

Here my expected result:

$'112.2012'
     [,1] [,2] [,3] [,4]
[1,]  174  191   31    4
[2,]    0  450    0    0
[3,]   11  188   49    1
[4,]   14  171   20    5

$'111.2012'
     [,1] [,2] [,3] [,4]
[1,]   45   14    0    1
[2,]    8  670    0    2
[3,]  190  157   44   59
[4,]   57   59    6   38

I really appreciate your ideas.

解决方案

You can use mapply , which is kind of multivariate version of lapply, for this task

fun <- function(Z, p) {
  imp <- as.vector(cbind(imp=rowSums(Z)))
  exp <- as.vector(t(cbind(exp=colSums(Z))))
  x = p + imp
  ac = p + imp - exp  
  einsdurchx = 1/as.vector(x)    
  einsdurchx[is.infinite(einsdurchx)] <- 0
  A = Z %*% diag(einsdurchx)
  R = solve(diag(length(p))-A) %*% diag(p)
  C = ac * einsdurchx
  R_bar = diag(as.vector(C)) %*% R
  rR_bar = round(R_bar)
  return(rR_bar)
}

Z <- list("111.2012"= matrix(c(0,0,100,200,0,0,0,0,50,350,0,50,50,200,200,0),
                             nrow = 4, ncol = 4, byrow = T),
           "112.2012"= matrix(c(10,90,0,30,10,90,0,10,200,50,10,350,150,100,200,10),
                              nrow = 4, ncol = 4, byrow = T))
p <- list("111.2012"=c(200, 1000, 100, 10),
          "112.2012"=c(300, 900, 50, 100))


mapply(fun, Z, p, SIMPLIFY = FALSE)
## $`111.2012`
##      [,1] [,2] [,3] [,4]
## [1,]  174  191   31    4
## [2,]    0  450    0    0
## [3,]   11  188   49    1
## [4,]   14  171   20    5

## $`112.2012`
##      [,1] [,2] [,3] [,4]
## [1,]   45   14    0    1
## [2,]    8  670    0    2
## [3,]  190  157   44   59
## [4,]   57   59    6   38

这篇关于R:如何在两个列表上运行函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆