我知道您想要什么,但在R中没有实现这个功能。我不知道是否有已经实现了这个功能的包,但是自己编写也不难。
一个可行的方法是将包含代码的数据框添加到属性中。为了防止整个数据框被重复并节省空间,我会在该数据框中添加索引,而不是重新构建完整的数据框。
例如:
NACode <- function(x,code){
Df <- sapply(x,function(i){
i[i %in% code] <- NA
i
})
id <- which(is.na(Df))
rowid <- id %% nrow(x)
colid <- id %/% nrow(x) + 1
NAdf <- data.frame(
id,rowid,colid,
value = as.matrix(x)[id]
)
Df <- as.data.frame(Df)
attr(Df,"NAcode") <- NAdf
Df
}
这允许做到以下几点:
> Df <- data.frame(A = 1:10,B=c(1:5,-1,-2,-3,9,10) )
> code <- list("Missing"=-1,"Not Answered"=-2,"Don't know"=-3)
> DfwithNA <- NACode(Df,code)
> str(DfwithNA)
'data.frame': 10 obs. of 2 variables:
$ A: num 1 2 3 4 5 6 7 8 9 10
$ B: num 1 2 3 4 5 NA NA NA 9 10
- attr(*, "NAcode")='data.frame': 3 obs. of 4 variables:
..$ id : int 16 17 18
..$ rowid: int 6 7 8
..$ colid: num 2 2 2
..$ value: num -1 -2 -3
该函数还可以调整以添加一个额外的属性,为不同的值提供标签。详见此问题。您可以通过以下方式进行反转换:
ChangeNAToCode <- function(x,code){
NAval <- attr(x,"NAcode")
for(i in which(NAval$value %in% code))
x[NAval$rowid[i],NAval$colid[i]] <- NAval$value[i]
x
}
> Dfback <- ChangeNAToCode(DfwithNA,c(-2,-3))
> str(Dfback)
'data.frame': 10 obs. of 2 variables:
$ A: num 1 2 3 4 5 6 7 8 9 10
$ B: num 1 2 3 4 5 NA -2 -3 9 10
- attr(*, "NAcode")='data.frame': 3 obs. of 4 variables:
..$ id : int 16 17 18
..$ rowid: int 6 7 8
..$ colid: num 2 2 2
..$ value: num -1 -2 -3
这样可以只更改您想要的代码,如果有必要的话。当没有参数时,该函数可以适应返回所有代码。可以构建类似的函数来基于代码提取数据,我猜你自己可以想出那个。
但简单来说:使用属性和索引可能是一种不错的方法。
code
列表可以接受NAs而不仅仅是负整数和正整数,那将会很好。 - Matt Bannert