如何在R中批量将满足条件的列值替换为列名?
问题:批量替换文档词矩阵中大于0的值为对应列名
原始数据框
df_names_tkns <- tibble::tribble( ~name, ~aaa, ~ddd, ~downing, ~eee, ~london, ~street, ~bbb, ~broadway, ~ccc, ~new, ~york, "AAA LONDON DOWNING STREET DDD EEE", 1L, 1L, 1L, 1L, 1L, 1L, NA, NA, NA, NA, NA, "AAA NEW YORK BROADWAY BBB CCC", 1L, NA, NA, NA, NA, NA, 1L, 1L, 1L, 1L, 1L )
需求:将第2列及以后所有列中x>0的值替换为对应列的列名,保留原NA值不变。
错误尝试及原因
尝试1:使用基础if函数
df_names_tkns2 <- df_names_tkns |> mutate(across(2:ncol(df_names_tkns), function (x) if (x > 0) cur_column(x) else x))
报错信息:
Caused by error in `across()`: ! Problem while computing column `aaa`. Caused by error in `if (x > 0) ...`: ! the condition has length > 1
错误原因:
- 基础
if是标量函数,只能处理单个值,无法处理整列向量 cur_column()不需要传参,它会自动获取当前处理的列名
尝试2:使用case_when但参数错误
df_names_tkns2 <- df_names_tkns |> mutate( across( 2:ncol(df_names_tkns), ~ case_when(.x > 1 ~ cur_column(.x)) ) ) )
报错信息:
Caused by error in `across()`: ! Problem while computing column `aaa`. Caused by error in `cur_column()`: ! unused argument (aaa)
错误原因:
cur_column()无需传入参数,直接调用即可- 条件写为
.x>1但实际值是1,逻辑不匹配;且case_when未覆盖所有情况,未匹配的行会被强制转为NA(类型可能不兼容)
正确实现方式
方法1:用ifelse(向量化条件判断)
df_names_tkns2 <- df_names_tkns |> mutate(across(2:ncol(.), ~ ifelse(.x > 0, cur_column(), .x)))
说明:
ifelse是向量化函数,可直接处理整列向量cur_column()自动获取当前列名,无需传参- 用
2:ncol(.)替代原数据框名,写法更灵活
方法2:用case_when(需覆盖所有分支)
df_names_tkns2 <- df_names_tkns |> mutate(across(2:ncol(.), ~ case_when( .x > 0 ~ cur_column(), TRUE ~ as.character(.x) # 统一类型,保留原NA值 )))
说明:
TRUE ~ ...分支用来处理不满足条件的情况(此处为NA)- 因列名是字符型,原列是整数型,需用
as.character(.x)统一类型,避免类型不匹配报错
处理后结果
| name | aaa | ddd | downing | eee | london | street | bbb | broadway | ccc | new | york |
|---|---|---|---|---|---|---|---|---|---|---|---|
| AAA LONDON DOWNING STREET DDD EEE | aaa | ddd | downing | eee | london | street | NA | NA | NA | NA | NA |
| AAA NEW YORK BROADWAY BBB CCC | aaa | NA | NA | NA | NA | NA | bbb | broadway | ccc | new | york |
内容的提问来源于stack exchange,提问作者Jacek Kotowski
相关产品推荐
相关产品推荐

