如何基于列索引替换R数据集中指定列的零值?
按索引列替换对应列值的简便实现方法
我有一个R数据集,包含多列全零值和一列数值型索引列,需要将与索引列数值匹配的列(1对应第一列,2对应第二列……)中的零值替换为1。示例如下:
input <- tibble(X1 = c(0,0,0,0), X2 = c(0,0,0,0), X3 = c(0,0,0,0), index = c(1,2,2,3)) output <- tibble(X1 = c(1,0,0,0), X2 = c(0,1,1,0), X3 = c(0,0,0,1), index = c(1,2,2,3))
我已经实现了一种解决方案,但想了解更简便的写法(比如Base R实现),当前方案代码如下:
input %>% select(index) %>% bind_cols(map2_dfc(.x = c('X1', 'X2', 'X3'), .y = 1:3, .f = ~input %>% transmute(!!sym(.x) := if_else(.y == index, 1, 0))))
以下是两种更简洁的实现方式:
Base R 实现
利用矩阵索引直接赋值,高效且代码简洁:
# 复制原数据集避免修改原始数据 input_base <- input # 获取非索引列的数量 non_index_cols <- ncol(input_base) - 1 # 构造行、列匹配的索引对 row_indices <- seq(nrow(input_base)) col_indices <- input_base$index # 给对应位置赋值为1 input_base[cbind(row_indices, col_indices)] <- 1
运行后input_base与目标output完全一致。
Tidyverse 简化写法
用across函数批量处理列,代码更直观:
input_tidy <- input %>% mutate(across(X1:X3, ~if_else(cur_column() == paste0("X", index), 1, .x)))
这里通过cur_column()获取当前处理的列名,与paste0("X", index)生成的对应列名匹配,匹配成功则设为1,否则保留原0值。
内容的提问来源于stack exchange,提问作者oriloc
相关产品推荐
相关产品推荐

