r - 修复由 9 表示的 NA(例如:99、999、9999)匹配 data.table(或 fread)中的列宽
问题描述
文本文件中的数据通常具有代表 NA 的可变长度的 9 序列。也就是说,代表 NA 的 9 的数量取决于每个变量中的字符数。例如:
- 一个 2 位的州代码将有 99 个代表 NA
- 一个 3 位变量将有 999 个代表 NA。请注意,在这种情况下,99 可能是合法(非 NA)值。
清除这些值的最佳方法是什么?
请注意,在 中fread
,na.values=c('99','999')
不是一个理想的选择,因为它会破坏 3 位变量中的合法 99 值。
假设我有data.table
d
, 和两组数字列
cols_2digit <- c('a','b')
cols_3digit <- c('c','d')
如何在每组的所有列中一次用 NA 替换 9 的序列?集的数量是有限的,所以每集一个命令就可以了。
OBS:这些可变长度的 NA 代码让人联想到固定宽度文件 (fwf),即使现代文件以 csv 提供(这可能在列中为 NA 采用标准的“999999”值)。
解决方案
我们可以set
通过循环使用“cols_2digit”或“cols_3digit”中指定的列并更改列中的值
for(j in cols_2digit) set(d, i = which(d[[j]] == '99'), j = j, value = NA_character_)
for(j in cols_3digit) set(d, i = which(d[[j]] == '999'), j = j, value = NA_character_)
或者另一种选择是Map
d[, c(cols_2digit, col2_3digit) :=
Map(function(dat, y) lapply(dat, function(x)
fifelse(x, x == y, NA_character_)), list(.SD[, ..cols_2digit],
.SD[, ..cols_3digit]), list('99', '999')) ]
此外,另一种选择是根据最大频率查找列宽,而不是在不同的集合上执行此操作
Mode <- function(x) {
ux <- unique(x)
ux[which.max(tabulate(match(x, ux)))]
}
d[, lapply(.SD, function(x) {
# get the most frequent column width
colwidth <- Mode(nchar(x))
# if it is max
# colwidth <- max(nchar(x))
# get the elements that are only 9 from start (`^`) to end (`$`)
i1 <- grepl('^9+$', x)
# do the assignment based on the index
x[i1][nchar(x[i1]) == colwidth] <- NA_character_
x
})]
推荐阅读
- vb.net - 如何删除表单关闭时正在运行的exe
- html - 使用 CSS 选择器定位动态 CSS 元素
- javascript - 两个 jquery 下拉菜单在创建页面上工作,但不在编辑页面上
- sql - 在加入另一个表时,如何在每个案例的案例语句中给出 where 条件
- html - 将 AWS 中使用的某些百分比替换为 $25 的编码名称是什么
- sql-server - 如何在 SQL Server 中创建以 PRIMARY 为列名的表?
- python - pysnmp 自定义 MIB-Walk 失败
- html - 如何仅显示图像名称而不是完整的图像路径
- javascript - 这个使用 API 的 Alexa 意图有什么错误?
- pytorch - 多维向量的 Torch 选择索引