mar*_*aab 2 r dplyr purrr tidyverse
如果满足特定条件,我喜欢将一列的值替换为另一列的值。下面是一个玩具示例,我首先手动实现此目标,然后针对该问题起草一个有点笨拙的编程解决方案。(当然,我的真实数据包含更多变量,并且还需要更复杂的条件替换值)
\nlibrary(dplyr)\nlibrary(purrr)\n\n# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n## example data\nset.seed(123)\ndf <- tibble(\n x = sample(0:1, 10, replace = T),\n x_99 = sample(3:4, 10, replace = T),\n y = sample(0:1, 10, replace = T),\n y_99 = sample(3:4, 10, replace = T)\n)\n\ndf\n#> # A tibble: 10 \xc3\x97 4\n#> x x_99 y y_99\n#> <int> <int> <int> <int>\n#> 1 0 4 0 3\n#> 2 0 4 1 4\n#> 3 0 4 0 3\n#> 4 1 3 0 4\n#> 5 0 4 0 4\n#> 6 1 3 0 3\n#> 7 1 4 1 3\n#> 8 1 3 1 3\n#> 9 0 3 0 3\n#> 10 0 3 1 4\n\n# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n# manual mutate\n\ndf |>\n transmute(\n x = ifelse(x == 0, x_99, x),\n y = ifelse(y == 0, y_99, y)\n )\n#> # A tibble: 10 \xc3\x97 2\n#> x y\n#> <int> <int>\n#> 1 4 3\n#> 2 4 1\n#> 3 4 3\n#> 4 1 4\n#> 5 4 4\n#> 6 1 3\n#> 7 1 1\n#> 8 1 1\n#> 9 3 3\n#> 10 3 1\n\n# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n# verbose programmatic solution\n\nhelper <- function(df, x, xnew) {\n df[df[x] == 0, ][, x] <- df[df[x] == 0, ][, xnew]\n return(tibble(df[x]))\n}\n\ncol.vec1 <- c("x", "y")\ncol.vec2 <- paste0(col.vec1, "_99")\n\nmap2(\n col.vec1, col.vec2,\n ~ helper(df, .x, .y)\n) |>\n bind_cols()\n#> # A tibble: 10 \xc3\x97 2\n#> x y\n#> <int> <int>\n#> 1 4 3\n#> 2 4 1\n#> 3 4 3\n#> 4 1 4\n#> 5 4 4\n#> 6 1 3\n#> 7 1 1\n#> 8 1 1\n#> 9 3 3\n#> 10 3 1\nRun Code Online (Sandbox Code Playgroud)\n由reprex 包于 2022 年 9 月 11 日创建(v2.0.1)
\n我实际上主要使用 tidyverse 工具进行数据清理。但在这种情况下,这绝对超出了我的能力范围。我仍然找到了一个解决方案,但我很确定有一个更优雅且更简洁的解决方案。我非常感谢您的建议。
\n我想看across一下cur_column()会对你有用。您真正需要更改的唯一一件事是c(x, y)采用某种清晰整洁的方式来识别列。
df %>%
mutate(
across(c(x, y), ~ if_else(. == 0L, get(paste0(cur_column(), "_99")), .))
)
# # A tibble: 10 x 4
# x x_99 y y_99
# <int> <int> <int> <int>
# 1 4 4 3 3
# 2 4 4 1 4
# 3 4 4 3 3
# 4 1 3 4 4
# 5 4 4 4 4
# 6 1 3 3 3
# 7 1 4 1 3
# 8 1 3 1 3
# 9 3 3 3 3
# 10 3 3 1 4
Run Code Online (Sandbox Code Playgroud)