为什么na.rm = TRUE对于R中的加权SD不起作用?

问题描述 投票:2回答:1

我有一个包含房价的10列数据框,在某些情况下,包含NA。我想创建一个新列weighted sd,但是对于具有几个NA的行,我得到以下错误。

Error in e2[[j]] : subscript out of bounds

我每行使用的内容(并且适用于没有NA的行:

weighted.sd(my.df[40,2:10], c(9,9,9,9,9,9,9,9,9), na.rm = TRUE)

示例

library(radiant.data)
data("mtcars")
mtcars[mtcars == 0] <- NA
weighted.sd(mtcars[18,1:11], c(11,11,11,11,11,11,11,11,11,11,11), na.rm = TRUE)#works
weighted.sd(mtcars[5,1:11], c(11,11,11,11,11,11,11,11,11,11,11), na.rm = TRUE)#issue here

这里是什么问题,如何创建每行具有加权SD的新列?

r na standard-deviation
1个回答
0
投票

问题似乎是weighted.sd()无法像预期的那样跨数据帧的行运行。

正在运行weighted.sd,我们可以看到代码:

weighted.sd <- function (x, wt, na.rm = TRUE) 
{
  if (na.rm) {
    x <- na.omit(x)
    wt <- na.omit(wt)
  }
  wt <- wt/sum(wt)
  wm <- weighted.mean(x, wt)
  sqrt(sum(wt * (x - wm)^2))
}

在您的示例中,您不是为x输入向量,而是为数据帧的单行输入。由于na.omit(x)的值,而不是向量的元素,函数NA将删除整个行。

您可以尝试使用as.numeric()将行转换为向量,但是由于如何从NA中删除wt,此功能也会失败。

看来这可能是您想要的。当然,您必须小心输入x的有效列。

weighted.sd2 <- function (x, wt, na.rm = TRUE) {

  x <- as.numeric(x)

  if (na.rm) {
    is_na <- is.na(x)

    x <- x[!is_na]
    wt <- wt[!is_na]
  }

  wt <- wt/sum(wt)
  wm <- weighted.mean(x, wt)
  sqrt(sum(wt * (x - wm)^2))
}
weighted.sd2(mtcars[18,1:11], c(11,11,11,11,11,11,11,11,11,11,11), na.rm = TRUE)#works
# [1] 26.76086
weighted.sd2(mtcars[5,1:11], c(11,11,11,11,11,11,11,11,11,11,11), na.rm = TRUE)#issue here
# [1] 116.545

0
投票

如果您按CTRL键并单击weigted.sd函数,则可以看到源代码:

function (x, wt, na.rm = TRUE) 
{
  if (na.rm) {
    x <- na.omit(x)
    wt <- na.omit(wt)
  }
  wt <- wt/sum(wt)
  wm <- weighted.mean(x, wt)
  sqrt(sum(wt * (x - wm)^2))
}

运行时,值向量包含不带NA的值,并且会减少。但是weigth向量的长度与以前相同,从而导致错误。

解决方案将是:

weighted.sd(mtcars[5,!is.na(mtcars[5,1:11])], 
c(11,11,11,11,11,11,11,11,11,11,11)[!is.na(mtcars[5,1:11])], na.rm = TRUE)

不是很优雅...但是可以做到!

© www.soinside.com 2019 - 2024. All rights reserved.