[英]Using apply family functions when loop over arguments in a function in r
如何使用Apply类型函数之一循环遍历函数中的参数以使R中的代码更快? 例如,我创建了一个函数来计算三个随机变量的联合互信息
### Function to loop over: Joint Mutual Information I({x_1,x_2};y)
library(infotheo)
JMI <-function(x1,x2,y){
entropy(cbind(x1,x2),method="emp") + entropy(y, method="emp") -
entropy(cbind(x1,x2,y),method="emp")
}
假设我有两个矩阵(x1,x2)和一个向量y,例如:
#### randomly generate binary variables from a bernoulli distribution
set.seed(12345)
f1 <- rbinom(n=300,size=1,prob=0.5)
f2 <- rbinom(n=300,size=1,prob=0.5)
f3 <- rbinom(n=300,size=1,prob=0.5)
## creat y using xor operation of the two feature: x1 XOR x2
# this mean that y is 1 if f1[i]!=f2[i] and 0 otherwise
y <- ifelse(f1==f2,0,1)
x1 <-cbind(f1,f2)
x2 <- cbind(x1,f3)
现在,我想在JMI函数中循环x1和x2。 使用for循环如下所示:
# a length(x1) x length(x2)-Matrix with zeros
jmi <- matrix(rep(0,ncol(x2)*ncol(x1)),
nrow=ncol(x1),ncol=ncol(x2))
#### For loops to be avoided
for(i in 1:ncol(x1)){
for(j in 1:ncol(x2)){
jmi[i,j] <- JMI(x1[,i],x2[,j],y)
}#end out for(j)
}#end inner for(i)
有没有一种简单的方法来避免两个for循环?
这是使用apply的解决方案:
g <- expand.grid(1:ncol(x1), 1:ncol(x2))
v <- apply(g, 1, function(i) JMI(x1[, i[1]], x2[, i[2]], y))
jmi <- matrix(v, nrow = ncol(x1))
jmi
## [,1] [,2] [,3]
## [1,] 0.003809514 0.693147181 0.01082319
## [2,] 0.693147181 0.006485284 0.01152807
它分三个步骤进行:
x1
和x2
的列的索引是使用expand.grid
创建的。 这将创建一个包含两列的数据框g
,其中包含for循环所经过的i
和j
所有组合。 apply
用于遍历g
所有行,并将JMI
应用于x1
和x2
的对应列。 这产生向量v
。 v
转换为矩阵。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.