stringr::str_extract_all输出转数据框数值列及film_main数据清洗需求
解决方法:提取列名数字并过滤数据框列值
我来一步步帮你搞定这个需求:首先把str_extract_all返回的列表转换成可用的允许数字集合,然后针对每一列应用过滤规则,把不符合的值设为NA。
步骤1:加载包并准备数据
首先确保加载stringr,并保留原始列名(避免R自动修改特殊格式的列名):
library(stringr) # 示例数据集(添加check.names=FALSE保留原始列名) film_main <- data.frame( "grey..0..yellow..1.." = c(0, 1, 0, NA, 2), "grey..0..brown..1.." = c(3, 0, 0, NA, 2), "grey..0..blue..1...brown..2.." = c(0, 2, 1, 6, 1), "3grey..0..purple..1...brown..2.." = c(0, 1, 2, 3, NA), "3grey..0..purple..1...brown..2..brown..3.." = c(0, 1, 2, 3, NA), check.names = FALSE )
步骤2:提取列名中的数字并整理为允许值集合
str_extract_all返回的是列表,我们可以把每个列表元素转换成numeric类型的允许数字向量,后续用来过滤列值:
# 创建存储列名和允许数字的数据框 film <- data.frame(var = names(film_main), stringsAsFactors = FALSE) # 提取数字并转为numeric向量的列表 film$allowed_digits <- lapply(str_extract_all(film$var, "[:digit:]+"), as.numeric)
现在film$allowed_digits里每个元素对应一列的允许数字,比如第一列的允许数字是c(0,1),第四列是c(3,0,1,2)。
步骤3:应用过滤规则生成目标数据框
用mapply把每一列和对应的允许数字配对,过滤掉不在允许集合里的值(保留原始的NA):
# 对每一列执行过滤:值不在允许数字中则设为NA,原始NA保留 film_main_desired <- mapply(function(col, allowed) { ifelse(col %in% allowed | is.na(col), col, NA) }, film_main, film$allowed_digits, SIMPLIFY = FALSE) # 转换回数据框格式 film_main_desired <- as.data.frame(film_main_desired, check.names = FALSE)
验证结果
现在查看film_main_desired,和你期望的结果完全一致:
print(film_main_desired) # grey..0..yellow..1.. grey..0..brown..1.. grey..0..blue..1...brown..2.. 3grey..0..purple..1...brown..2.. 3grey..0..purple..1...brown..2..brown..3.. # 1 0 NA 0 0 0 # 2 1 0 2 1 1 # 3 0 0 1 2 2 # 4 NA NA NA 3 3 # 5 NA NA 1 NA NA
补充小技巧
如果想把film$allowed_digits从列表转成可读性更强的字符型(比如逗号分隔的字符串),可以用sapply配合paste:
film$allowed_str <- sapply(film$allowed_digits, paste, collapse = ", ")
这样allowed_str就是类似"0, 1"的字符串,方便快速查看每列的允许值,但过滤逻辑还是用numeric列表更直接。
内容的提问来源于stack exchange,提问作者Robbie
相关产品推荐
相关产品推荐

