为列表中各tibble的colA列填充带唯一编号的缺失值
问题
我有一个包含多个以连续数字命名的tibble的列表,每个tibble包含多列,其中colA列存在于所有tibble中:部分tibble的colA列填充了有效值,其余tibble的colA列则全为NA。
需要编写一个函数,实现当colA的值为NA时,将该列填充为格式为"i missing"的字符串,其中i是每个tibble独有的编号(可使用tibble的数字名称,或其他任意唯一编号)。原本考虑结合ifelse()和paste()实现,但无法理清具体思路。
示例代码如下:
`1` <- tibble(colA = c("a123", "a123", "a123", "a123"), colB = c("abc", "def", "ghi", "jkl")) `2` <- tibble(colA = c(NA, NA, NA, NA), colB = c("hij", "klm", "nop", "qrs")) `3` <- tibble(colA = c(NA, NA, NA, NA), colB = c("abc", "def", "ghi", "jkl")) `4` <- tibble(colA = c("e2b4", "e2b4", "e2b4", "e2b4"), colB = c("tuv", "wxy", "zab", "cde")) List1 <- list(`1`, `2`, `3`, `4`) List1
解决方案
方法1:用purrr::imap处理(tidyverse风格)
imap能同时遍历列表元素和它们的索引,刚好匹配需求。结合dplyr::mutate可以轻松替换NA值:
library(purrr) library(dplyr) filled_list <- imap(List1, function(tbl, idx) { tbl %>% mutate(colA = ifelse(is.na(colA), paste(idx, "missing"), colA)) }) # 验证结果(以第二个tibble为例) filled_list[[2]] #> # A tibble: 4 x 2 #> colA colB #> <chr> <chr> #> 1 2 missing hij #> 2 2 missing klm #> 3 2 missing nop #> 4 2 missing qrs
方法2:Base R原生实现
如果不想依赖tidyverse包,用mapply也能完成,逻辑和上面一致:
filled_list_base <- mapply(function(tbl, idx) { # 定位colA的NA值并替换 tbl$colA[is.na(tbl$colA)] <- paste(idx, "missing") tbl }, List1, seq_along(List1), SIMPLIFY = FALSE) # 验证结果(以第三个tibble为例) filled_list_base[[3]] #> # A tibble: 4 x 2 #> colA colB #> <chr> <chr> #> 1 3 missing abc #> 2 3 missing def #> 3 3 missing ghi #> 4 3 missing jkl
额外说明
- 替换后
colA的类型会统一为字符型,因为原NA是逻辑型,和字符串混合后自动转换,这符合需求。 - 如果你的列表是带命名的(比如
List1 <- list("1" =1, "2" =2, ...)),可以把代码里的idx换成列表的名称,比如paste(name, "missing"),这样就能用原本的数字命名作为编号。
内容的提问来源于stack exchange,提问作者BleepBloop
相关产品推荐
相关产品推荐

