R 将函数应用于矩阵或数据帧的每一行
假设我有一个n乘2的矩阵和一个以2向量为参数的函数。我想把这个函数应用到矩阵的每一行,得到一个n向量。如何在R中执行此操作 例如,我想计算三个点上二维标准正态分布的密度:R 将函数应用于矩阵或数据帧的每一行,r,function,matrix,apply,sapply,R,Function,Matrix,Apply,Sapply,假设我有一个n乘2的矩阵和一个以2向量为参数的函数。我想把这个函数应用到矩阵的每一行,得到一个n向量。如何在R中执行此操作 例如,我想计算三个点上二维标准正态分布的密度: 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]*sigm
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))
双变量密度(x=c(0,0),μ=c(0,0),σ=c(1,1),ρ=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您只需使用
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>
bvout[] <-apply(out, 1, FUN=bvnormdens, mu=c(-1,1), rho=0.6)
R>M
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
R> 应用(M,1,函数(x)2*x[1]+x[2])
[1] 4 10 16
R>
这需要一个矩阵,并对每一行应用一个(愚蠢的)函数。将额外的参数传递给函数,如第四、第五、。。。
apply()
的参数第一步是创建函数对象,然后应用它。如果需要具有相同行数的矩阵对象,可以预定义它并使用如图所示的object[]形式(否则返回值将简化为向量):
bvnormdens如果要应用sum或mean等常用函数,则应使用rowSums
或rowsmeans
,因为它们比apply(data,1,sum)
方法更快。否则,请坚持使用apply(数据,1,乐趣)
。您可以在有趣的参数之后传递其他参数(正如Dirk已经建议的):
如果要使用数据集的不同部分而不是单个值,另一种方法是使用rollappy(数据、宽度、乐趣等)
。使用宽度向量可以在数据集的不同窗口上应用函数。我用它来构建一个自适应过滤例程,虽然它不是很有效。这里是一个将函数应用于矩阵每一行的简短示例。
(此处,应用的函数将每行规格化为1。)
注意:必须使用t()
对apply()
的结果进行转置,以获得与输入矩阵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) ))
Apply做得很好,但速度很慢。
使用Sappy和vapply可能会有用。dplyr的rowwise也可能有用
让我们看一个如何对任何数据帧进行行积的示例
a = data.frame(t(iris[1:10,1:3]))
vapply(a, prod, 0)
sapply(a, prod)
请注意,在使用vapply/sapply/apply之前为变量赋值是一种很好的做法,因为这样可以大大减少时间。让我们看看微基准测试结果
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()是如何使用的谢谢!如果矩阵的行不是函数的第一个参数,该怎么办?如何指定将矩阵的每一行分配给函数的哪个参数?请阅读apply()
——它按行扫描(当第二个参数为1时,按列扫描),当前行(或列)始终是第一个参数。这就是事物的定义方式。@Tim:如果您使用一个内部R函数,而行不是第一个参数,请像Dirk那样做,并创建自己的自定义函数,其中行是第一个参数。plyr软件包提供了一系列此类函数。它还提供了更多的功能,包括并行处理。@cryptic0这个答案很晚,但对于谷歌来说,apply中的第二个参数是MARGIN
参数。这里的意思是将函数应用于行(dim(M)
中的第一个维度)。如果是2,它会将函数应用于列。如果使用b,比较apply系列可能更公平
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
a = data.frame(t(iris[1:10,1:3]))
vapply(a, prod, 0)
sapply(a, prod)
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))
)