假设我×2矩阵,并且需要2矢量作为它的一个参数的函数有正。我想给函数应用于矩阵中的每一行,并得到一个正向量。如何做到这一点的R'

例如,我想计算在三个点的2D标准正态分布的密度:

bivariate.density(x = c(0, 0), mu = c(0, 0), sigma = c(1, 1), rho = 0){
    exp(-1/(2*(1-rho^2))*(x[1]^2/sigma[1]^2+x[2]^2/sigma[2]^2-2*rho*x[1]*x[2]/(sigma[1]*sigma[2]))) * 1/(2*pi*sigma[1]*sigma[2]*sqrt(1-rho^2))
}

out <- rbind(c(1, 2), c(3, 4), c(5, 6))

如何函数应用于out的每行?

如何通过为其他参数值除了指向指定的方式功能?

有帮助吗?

解决方案

您只需使用apply()功能:

R> M <- matrix(1:6, nrow=3, byrow=TRUE)
R> M
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
R> apply(M, 1, function(x) 2*x[1]+x[2])
[1]  4 10 16
R> 

这需要一个矩阵,并应用(傻)函数的每一行。你传递额外的参数给功能第四,第五,...参数apply()

其他提示

如果你想申请的通用功能,如和或均值,你应该因为他们比rowSums方法快使用rowMeansapply(data, 1, sum)。否则,坚持apply(data, 1, fun)。可以传递FUN参数后附加参数(如德克已经建议):

set.seed(1)
m <- matrix(round(runif(20, 1, 5)), ncol=4)
diag(m) <- NA
m
     [,1] [,2] [,3] [,4]
[1,]   NA    5    2    3
[2,]    2   NA    2    4
[3,]    3    4   NA    5
[4,]    5    4    3   NA
[5,]    2    1    4    4

然后,你可以做这样的事情:

apply(m, 1, quantile, probs=c(.25,.5, .75), na.rm=TRUE)
    [,1] [,2] [,3] [,4] [,5]
25%  2.5    2  3.5  3.5 1.75
50%  3.0    2  4.0  4.0 3.00
75%  4.0    3  4.5  4.5 4.00

下面是将函数应用于矩阵中的每一行的一个简短的例子。 (这里,功能应用规格化的每一行设置为1。)

注意:的从apply()结果必须是的互换的使用t()获取布局作为输入矩阵A相同

A <- matrix(c(
  0, 1, 1, 2,
  0, 0, 1, 3,
  0, 0, 1, 3
), nrow = 3, byrow = TRUE)

t(apply(A, 1, function(x) x / sum(x) ))

<强>结果:

     [,1] [,2] [,3] [,4]
[1,]    0 0.25 0.25 0.50
[2,]    0 0.00 0.25 0.75
[3,]    0 0.00 0.25 0.75

第一步是使函数对象,然后施加它。如果希望有相同的行数的矩阵对象时,可以预先定义,并使用如图所示的对象[]形式(否则返回值将被简化为一个向量):

bvnormdens <- function(x=c(0,0),mu=c(0,0), sigma=c(1,1), rho=0){
     exp(-1/(2*(1-rho^2))*(x[1]^2/sigma[1]^2+
                           x[2]^2/sigma[2]^2-
                           2*rho*x[1]*x[2]/(sigma[1]*sigma[2]))) * 
     1/(2*pi*sigma[1]*sigma[2]*sqrt(1-rho^2))
     }
 out=rbind(c(1,2),c(3,4),c(5,6));

 bvout<-matrix(NA, ncol=1, nrow=3)
 bvout[] <-apply(out, 1, bvnormdens)
 bvout
             [,1]
[1,] 1.306423e-02
[2,] 5.931153e-07
[3,] 9.033134e-15

如果你想使用非默认参数等,则调用应该包含函数命名的参数:

bvout[] <-apply(out, 1, FUN=bvnormdens, mu=c(-1,1), rho=0.6)

应用()也可以在更高维阵列用于与MARGIN参数可以是一个矢量,以及一个整数。

应用做的工作做好,但速度很慢。 使用sapply和vapply可能是有用的。 dplyr的横行也可能是有用的 让我们来看看如何执行的任何数据帧的行之积的例子。

a = data.frame(t(iris[1:10,1:3]))
vapply(a, prod, 0)
sapply(a, prod)

注意,使用vapply / sapply /应用是很好的做法,因为它减少很多时间之前分配给变量。让我们来看看微基准测试结果。

a = data.frame(t(iris[1:10,1:3]))
b = iris[1:10,1:3]
microbenchmark::microbenchmark(
    apply(b, 1 , prod),
    vapply(a, prod, 0),
    sapply(a, prod) , 
    apply(iris[1:10,1:3], 1 , prod),
    vapply(data.frame(t(iris[1:10,1:3])), prod, 0),
    sapply(data.frame(t(iris[1:10,1:3])), prod) ,
    b %>%  rowwise() %>%
        summarise(p = prod(Sepal.Length,Sepal.Width,Petal.Length))
)

有在是如何被使用T()仔细观察

如果你想使用的数据集的变化部分,而不是一个单一的值的另一种方法是使用rollapply(data, width, FUN, ...)。使用宽度的向量允许您将数据集的不同窗口上应用的功能。我用这个构建自适应滤波程序中,虽然它不是很有效。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top