如何使用R包memisc批量设置data.set中所有项的缺失值?
问题:批量设置Memisc中data.set所有项的缺失值
Memisc是一款用于便捷处理调查数据的R包,它使用名为data.set的数据类型,该类型是item的列表,item类似于数据框中的因子/变量。我有一个data.set,其中-99代表拒绝回答的缺失值,NA代表不适用的情况。我想要为所有170个项设置missing.values(data$item) = c(-99),有没有简便方法,不用逐个复制粘贴修改?理想情况是不用for循环,但如果循环可行也希望了解方法。
补充说明
无法用dput()提供可复现数据,参考Memisc文档时发现foreach()函数似乎可用,但需要手动列所有列名,示例如下:
ds <- data.set( a = c(1,2,3,2,3,8,9), b = c(2,8,3,2,1,8,9), c = c(1,3,2,1,2,8,8) ) ds <- within(ds,{ foreach(x=c(a,b,c),{ # Lazy data documentation: labels(x) <- c( # a,b,c get value labels in one statement one = 1, two = 2, three = 3, "don't know" = 8, "refused to answer" = 9) missing.values(x) <- c(8,9) }) })
但我想知道是否可以用foreach()或for()指定“所有项”,即便不知道项的数量?虽然ds是列表(data.set属于列表的一种),但以下代码无效:
ds <- within(ds, { foreach(x=ds, missing.values(x) <- c(3)) }) missing.values(ds$a) #still 8 and 9, not 3
解决方案
方法1:用foreach结合列名批量处理
在within环境中不能直接遍历ds,需要通过列名引用元素。用names(ds)获取所有列名,循环中通过get(x)取出对应item,修改后再赋值回去:
ds <- within(ds, { foreach(x = names(ds), { item <- get(x) missing.values(item) <- c(-99) assign(x, item) }) })
方法2:用for循环遍历列名
这是最直接的方法,170列的规模完全不会有性能问题:
for (col in names(ds)) { missing.values(ds[[col]]) <- c(-99) }
方法3:用lapply批量转换
利用data.set的列表特性,用lapply遍历每个item修改缺失值,最后重新转为data.set类型:
ds <- as.data.set(lapply(ds, function(item) { missing.values(item) <- c(-99) return(item) }))
验证示例
用补充说明中的测试数据验证方法2:
ds <- data.set( a = c(1,2,3,2,3,8,9), b = c(2,8,3,2,1,8,9), c = c(1,3,2,1,2,8,8) ) for (col in names(ds)) { missing.values(ds[[col]]) <- c(-99) } missing.values(ds$a) # 输出 c(-99),符合预期
内容的提问来源于Stack Exchange,提问作者Ellie
相关产品推荐
相关产品推荐

