我写了一个函数,它使用花的宽度和长度来计算二元正态分布的密度。我想将该函数应用于数据帧,以计算每行的密度。我正试图使用apply((函数来实现这一点,但它给了我一个错误,说我的函数不是函数。当我将函数用于单行时,它确实有效,所以我不认为这是函数本身的问题。我试着研究一下,但找不到太多关于如何在apply((中实现用户定义函数的信息。这是我的代码和一些示例数据。
density_fn<- function(x, y, mu_x, mu_y, sigma){
mean_vec<- matrix(c((x - mu_x), (y - mu_y)))
sigma_det<- det(sigma)
sigma_inv<- solve(sigma)
frac<- 1/(2*pi*sqrt(sigma_det))
exponent<- exp(-0.5%*%t(mean_vec)%*%sigma_inv%*%mean_vec)
den_fn<- frac*exponent
return(den_fn)
}
flower<- data.frame(
Width = c(20, 32, 29),
Length = c( 51, 66, 48)
)
flower_w_mean<- 27
flower_l_mean<- 55
cov_matrix<- matrix(c(39, 0, 0, 93), nrow=2, ncol=2)
apply(flower, 1, FUN = density_fn(flower$Width, flower$Length,
flower_w_mean, flower_l_mean, cov_matrix))
最初,我得到了这个错误:
-0.5%*%t(mean_vec(%*%sigma_inv中的错误:不一致的参数
我认为这是我的协方差矩阵的问题,所以我去掉了函数的第一行以外的所有内容,并返回mean_vec
,这时我得到了这个错误:
match.fun(fun(中的错误:c("'density_fn(flower$Width,flower$Length,flower_w_mean,flower_l_mean,'不是函数、字符或符号","cov_matrix('不是函数或符号"(
有人知道如何将此函数正确应用于数据帧吗?
首先,让我解释一下您收到的两条错误消息。
第一个错误
-0.5%*%t(mean_vec(%*%sigma_inv中的错误:不一致的参数
此错误消息显示错误的原因是不符合规则的参数相乘。矩阵乘法A %*% B
的规则是,如果是矩阵,A
的列数必须等于B
的行数,如果是向量,则A
的长度必须等于。
在density_fn
中,定义mean_vec<- matrix(c((x - mu_x), (y - mu_y)))
使mean_vec
成为一个列恰好1且行数等于x
与y
组合的总长度的矩阵。因此,如果sigma_inv
>1,矩阵乘法CCD_ 12不符合规则。例如:
x <- 1:2 # length of 2
y <- 1:3 # length of 3
sigma <- matrix(1:4, nrow = 2)
sigma_inv <- solve(sigma)
mean_vec <- matrix(c(x - mean(x), y - mean(y)))
mean_vec # 1 row 5 columns
# [,1]
#[1,] -0.5
#[2,] 0.5
#[3,] -1.0
#[4,] 0.0
#[5,] 1.0
t(mean_vec) %*% sigma_inv
# Error in t(mean_vec) %*% sigma_inv : non-conformable arguments
如果CCD_ 13和CCD_。这就是为什么当您将此函数用于单行时,它确实有效。例如:
x <- 2 # length of 1
y <- 3 # length of 1
sigma <- matrix(1:4, nrow = 2)
mean_vec <- matrix(c(x - mean(x), y - mean(y)))
sigma_inv <- solve(sigma)
t(mean_vec) %*% sigma_inv
# [,1] [,2]
# [1,] 0 0
使函数在x
和y
的任何长度上正常工作的另一种方法是如下设置mean_vec <- matrix()
中的行数和列数:
mean_vec <- matrix(c((x - mu_x), (y - mu_y)),
ncol = nrow(sigma),
nrow = ncol(sigma))
然后将矩阵乘法CCD_ 18改变为标量乘法-0.5 * mean_vec
。
因此,函数变为:
density_fn <- function(x, y, mu_x, mu_y, sigma) {
mean_vec <- matrix(c((x - mu_x), (y - mu_y)),
ncol = nrow(sigma),
nrow = ncol(sigma))
sigma_det <- det(sigma)
sigma_inv <- solve(sigma)
frac <- 1 / (2 * pi * sqrt(sigma_det))
exponent <- exp(-0.5 * t(mean_vec) %*% sigma_inv %*% mean_vec)
den_fn <- frac * exponent
return(den_fn)
}
第二个错误
match.fun(fun(:c('density_fn(花$Width,花$Length,flower_w_mean,flower_l_mean,'不是函数、字符或符号"'cov_matrix('不是函数、字符或符号"(
此错误消息显示未正确指定apply
中FUN
的值。根据apply
的文档,分配给FUN
的值应为
通常是一个函数或符号(例如,后引号名称(或者指定要从中搜索的函数的字符串应用的调用环境
这意味着您应该只向FUN
提及函数名。函数的附加参数(第二个参数、第三个参数…(应在FUN
之后提及,而不是在FUN
中提及。请查看?apply
了解详细信息。
然而,仅此步骤并不能解决问题,因为apply
适用于单变量输入。因为您的输入是多变量的,所以mapply
更适合。其他选项包括Map
和使用for
等的环路。
如何使用mapply
应用函数
最好用一个简单的例子来解释。请查看?mapply
了解详细信息。假设您有x
和y
,并且您想要得到z = 2x + 3y
。您希望将函数矢量化为x
和y
。
x <- c(3,4,5)
y <- c(10,20, 30)
myfun <- function(x,y) 2*x + 3*y
z <- mapply(myfun, x, y)
z
#[1] 36 68 100
如果在myfun
中有x
和y
以外的参数,则应将它们分配给MoreArgs
。以下是使用density_fn
的示例。
mapply(density_fn, x = flower$Width, y = flower$Length, MoreArgs = list(
mu_x = flower_w_mean,
mu_y = flower_l_mean,
sigma = cov_matrix))
# [,1] [,2] [,3]
# [1,] 0.001293784 0.001000747 0.001929141
# [2,] 0.001293784 0.001000747 0.001929141
# [3,] 0.001293784 0.001000747 0.001929141
# [4,] 0.001293784 0.001000747 0.001929141
这些步骤不会产生错误。然而,由于我对这个主题的了解有限,我不能保证这些步骤能像你想要的那样正确地表示二元正态分布的密度函数。