r - 如何将 NA 值替换为赋予相同 ID 的先前非 NA 值
问题描述
我在 R 中工作并且正在使用 data.table。我有一个如下所示的数据集:
ID country_id weight
1 BGD 56
1 NA 57
1 NA 63
2 SA 12
2 NA 53
2 SA 54
如果 country_id 中的值为 NA 我需要将其替换为赋予相同 ID 的 non-na country_id 值。我希望数据集看起来像这样:
ID country_id weight
1 BGD 56
1 BGD 57
1 BGD 63
2 SA 12
2 SA 53
2 SA 54
该数据集包含数百万个 ID,因此无法手动修复每个 ID。
谢谢你的帮助!
编辑:解决了!
我使用了这个代码:dt[, country_id := country_id[!is.na(country_id)][1], by = ID]
解决方案
另一种选择是使用连接:
DT[is.na(country_id), country_id :=
DT[!is.na(country_id)][.SD, on=.(ID), mult="first", country_id]]
解释:
DT[is.na(country_id)
将数据集子集到 country_id 列中具有 NA 的数据集.SD
是上一步中的数据子集(也是 data.table)。DT[!is.na(country_id)][.SD, on=.(ID)
左连接使用.SD
作为键。DT[!is.na(country_id)]
ID
j=country_id
从右表返回 country_id 列DT[!is.na(country_id)]
,如果有多个匹配项,则mult="first"
返回第一个匹配项。country_id :=
country_id
将DT 行中为 TRUE的列更新为is.na(country_id)
连接的结果。
根据 Andrew 的时序代码和类似但更大的数据:
library(data.table)
set.seed(42)
nr <- 1e7
dt <- data.table(ID = rep(1:(nr/4), each = 4),
country_id = rep(rep(c("BGD", "SA", "USA", "DEN", "THI"), each = 4)),
weight = sample(10:100, nr, TRUE))
dt[sample(1:nr, nr/2), country_id := NA]
DT <- copy(dt)
microbenchmark::microbenchmark(
first_nonmissing = dt[, country_id := country_id[!is.na(country_id)][1L], by = ID],
use_join=DT[is.na(country_id), country_id := DT[!is.na(country_id)][.SD, on=.(ID), mult="first", country_id]],
times = 1L
)
时间:
Unit: milliseconds
expr min lq mean median uq max neval
first_nonmissing 3282.1373 3282.1373 3282.1373 3282.1373 3282.1373 3282.1373 1
use_join 554.5314 554.5314 554.5314 554.5314 554.5314 554.5314 1
推荐阅读
- javascript - Bootstrap 4:如果脚本无效,则将“滚动到第一个无效字段”添加到不“提交”
- powershell - New-ADuser - 参数 OtherAttributes
- laravel - 在 Laravel 中将 HTMLCanvasElement 存储为 JPG
- excel - 如何使用 OpenPyXL 从返回的元组中获取值
- java - 尝试将实体映射到 DTO 对象时,ModelMapper 返回 NULL
- javascript - CSS设置避免点击时出现上传弹出窗口
- vba - VBA脚本根据日期选择特定列下的数据
- wordpress - 为什么我的 wordpress 网站突然显示为索引列表?
- php - 如何使用 JSON/jQuery 和 PHP 数据进行比较
- html - Angular Material 修复了 Sidenav 格式问题