为什么不变异填充所有行?正在使用 mutate 和 ifelse 从另一个数据框中查找估算值

Why didn't mutate fill all rows? Was using mutate and ifelse to look up imputed values from another dataframe

这是交易。试图使用 plyr 包中的 mutate 从另一个数据帧中查找适当的值,如果原始数据帧中的 v 变量是 NA。查找的值应该进入一个新变量 imputed。我还为此查找目的定义了一个自定义函数。

代码如下:

if(!require(plyr)){
  install.packages("plyr")
  library(plyr)
}
df = data.frame(d=c(1,1,1,2,2,2,3,3,3),
                g=rep(c(1,2,3),3),
                v=c(5,NA,NA,5,NA,NA,5,NA,NA))
imputed = data.frame(g=c(1,2,3),
                     v=c(5,10,15))
getImputed = function(p){
  imputed[imputed$g==p,"v"]
}
df = mutate(df,imputed=ifelse(is.na(v),getImputed(g),v))
df

这是生成的数据帧:

  d g  v imputed
1 1 1  5       5
2 1 2 NA      10
3 1 3 NA      15
4 2 1  5       5
5 2 2 NA      NA
6 2 3 NA      NA
7 3 1  5       5
8 3 2 NA      NA
9 3 3 NA      NA

可以看到,mutate 只成功填充了前 3 行。 ifelse 函数很可能是问题所在,但我不明白为什么:(

奇怪的是,如果 imputed 数据框有 4 行,像这样:

imputed = data.frame(g=c(1,2,3,4),
                     v=c(5,10,15,20))

然后 df 数据框被正确填充:

  d g  v imputed
1 1 1  5       5
2 1 2 NA      10
3 1 3 NA      15
4 2 1  5       5
5 2 2 NA      10
6 2 3 NA      15
7 3 1  5       5
8 3 2 NA      10
9 3 3 NA      15

但是 R 给了我一个警告说:

Warning message:
In imputed$g == p :
  longer object length is not a multiple of shorter object length

我是不是忽略了什么?

问题出在您的 getImputed 函数上。 mutate 函数不会遍历行。它将列作为向量传递给函数,因此每个函数基本上都称为一个。如果您传递单个值,您的 getInputed 函数可以工作,但对于向量

则效果不佳
getImputed(1)
# [1] 5

getImputed(c(1,2))
# [1] 5 10
# Warning message:
# In imputed$g == p :
#   longer object length is not a multiple of shorter object length

编写函数的更好方法是

getImputed2 <- function(p){
  imputed$v[match(p, imputed$g)]
}

这将正确处理值向量

mutate(df,imputed=ifelse(is.na(v),getImputed2(g),v))
#   d g  v imputed
# 1 1 1  5       5
# 2 1 2 NA      10
# 3 1 3 NA      15
# 4 2 1  5       5
# 5 2 2 NA      10
# 6 2 3 NA      15
# 7 3 1  5       5
# 8 3 2 NA      10
# 9 3 3 NA      15

你也可以考虑加入和替换

mutate(join(df, setNames(imputed, c("g","v2")), by=c(g="g")), 
    v=ifelse(is.na(v), v2, v), v2=NULL)