我有一个包含房价的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的新列?
问题似乎是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
如果您按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)
不是很优雅...但是可以做到!