简体   繁体   English

R代码中的怪异错误:示例时刻

[英]Weird bug in R code: Sample Moments

CalculateSampleMomentAroundZero <- function(x) {
  # Computes the sample moments (up to fourth order) around zero
  #
  # Args:
  #   x: A vector of numbers whose sample moments around zero
  #      will be calculated
  #
  # Returns:
  #   A list that contains the sample moments (up to fourth order)
  #   of the numbers in vector x.

  n <- length(x)
  moment.zero <- lapply(1:4, function(i) (1/n) * sum(x^i))
  names(moment.zero) <- c("first", "second", "third", "fourth")

  moment.zero
}

CalculateSampleMomentAroundMean <- function(x) {
  # Computes the sample moment (up to fourth order) around the mean
  #
  # Args:
  #   x: A vector of numbers whose sample moments around the mean 
  #      will be computed
  #
  # Returns:
  #   A list that contains the sample moments (up to fourth order) 
  #   of the numbers in vector x.

  #
  # Uses the function to calculate sample moments around zero to
  #  obtain the mean (sample moment around zero of first order) of 
  #  the numbers in vector x.
  #
  moments.around.zero <- CalculateSampleMomentAroundZero(x)
  xbar <- moments.around.zero$first

  n <- length(x)
  moment.mean <- lapply(1:4, function(i) (1/n) * sum((x - xbar)^i))
  names(moment.mean) <- c("first", "second", "third", "fourth")

  moment.mean
} 

skewnesskurtosis <- function(x) {
  # Computes the skewness and kurtosis of a vector of numbers
  #
  # Args:
  #   x: A vector of numbers whose skewness and kurtosis will be 
  #      computed.
  #
  # Returns:
  #   A list that contains the skewness and kurtosis of the numbers 
  #   in vector x.

  #
  # Uses the function to compute sample moments around the mean to 
  #  obtain the second, third, and fourth orders of the sample    
  #  moments around the mean.
  #
  moments.around.mean <- CalculateSampleMomentAroundMean(x)
  mu2 <- moments.around.mean$second
  mu3 <- moments.around.mean$third
  mu4 <- moments.around.mean$fourth

  skew <- mu3 / (mu2)^(3/2)
  kurt <- (mu4 / (mu2)^(2)) - 3
  sk <- list(skewness = skew, kurtosis = kurt)

  sk
}

I checked my output by using the functions in the moments library, and I get the same results for my first function. 我通过使用moments库中的函数检查了输出,对于第一个函数,我得到的结果相同。 The second function, however, is a little odd. 但是,第二个功能有点奇怪。 The second, third, and fourth moments match up, but not the first. 第二,第三和第四时刻匹配,但第一时刻不匹配。 This is weird, because how could the first moment be incorrect, while the rest are right? 这很奇怪,因为当第一刻正确的时候,第一刻怎么可能是错误的? I looked over my code many times, and I still can't find the error. 我检查了很多遍代码,但仍然找不到错误。 Could someone please help? 有人可以帮忙吗?

Edit: here's my input and output 编辑:这是我的输入和输出

x <- rnorm(5)

CalculateSampleMomentAroundMean(x)
$first
[1] -2.220446e-17

$second
[1] 0.2923308

$third
[1] -0.02291481

$fourth
[1] 0.1172637

> moment(x, order = 1, central = TRUE)
[1] -8.326673e-18

> moment(x, order = 2, central = TRUE)
[1] 0.2923308

> moment(x, order = 3, central = TRUE)
[1] -0.02291481

> moment(x, order = 4, central = TRUE)
[1] 0.1172637

You function is calculating things correctly. 您的功能是正确计算事物。 Because the calculation was performed differently in the moments function, the errors from the floating point representation of the numbers added up differently. 由于在moments函数中执行的计算方式不同,因此浮点数表示形式的误差加起来也不同。

Essentially what is happening is because the machine cannot represent any given floating point number exactly, when you try to do math on a number like sqrt(2) , small errors are introduced. 本质上发生的事情是因为机器无法准确表示任何给定的浮点数,因此当您尝试对sqrt(2)类的数字进行数学运算时,会引入一些小错误。 These errors add up differently depending on what you are doing. 根据您的操作,这些错误的总和会有所不同。 For example, if you multiply and then add, the floating point error may be different than if you added and then multiplied. 例如,如果先乘后加,则浮点误差可能与先乘后乘的浮点误差不同。 In any event, the error is less than a value called machine precision which is about 1e-16. 无论如何,该误差都小于称为机器精度的值,该值约为1e-16。 Since the differences between moments and your function are within that value, the difference is not meaningful. 由于moments和您的功能之间的差异在该值之内,因此差异没有意义。

I would suggest that if the moment is 1, you automatically return 0. That would avoid this problem. 我建议如果此刻为1,则自动返回0。这样可以避免此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM