Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 将函数应用于矩阵或数据帧的每一行_R_Function_Matrix_Apply_Sapply - Fatal编程技术网

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

假设我有一个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]*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))
)