r - R - dplyr/purrr - 从现有列对的函数创建新列
问题描述
我遇到了 dplyr::mutate 几次的绊脚石,因为我不知道如何基于函数(例如求和或其他任何东西)创建新列,该函数将基于所有对创建新列的两组输入列。部分演示如下:
#Input data
set.seed(100)
in_dat <- tibble(x1 = sample(x = c(1:10, NA_real_), size = 1000, replace = TRUE),
x2 = sample(x = c(1:10, NA_real_), size = 1000, replace = TRUE),
x3 = sample(x = c(1:10, NA_real_), size = 1000, replace = TRUE),
x4 = sample(x = c(1:10, NA_real_), size = 1000, replace = TRUE),
y1 = sample(x = c(1, 0, NA_real_), size = 1000, replace = TRUE),
y2 = sample(x = c(1, 0, NA_real_), size = 1000, replace = TRUE),
y3 = sample(x = c(1, 0, NA_real_), size = 1000, replace = TRUE),
y4 = sample(x = c(1, 0, NA_real_), size = 1000, replace = TRUE),
y5 = sample(x = c(1, 0, NA_real_), size = 1000, replace = TRUE),
y6 = sample(x = c(1, 0, NA_real_), size = 1000, replace = TRUE))
#Output data with 1 column pair; all pairs between x and y should be computed
out_dat_1col <- in_dat %>%
mutate(miss_x1y1 = if_else(is.na(x1) & is.na(y1), TRUE, FALSE))
这将检查是否有一对 x 和 y 列都具有缺失值并在新列中标记为 TRUE。不过,这只是一对,我想要一种方法来对 x 和 y 列之间的所有对执行此操作,而不是在它们自己的 mutate 行中手动编码每一对。我认为 purrr 应该能够做到这一点,但我还没有弄清楚 map 变体的正确语法,或者也可能减少。我目前从两者map2_dfc
(将新列附加到现有列上)bind_cols
和(x 变量)和(y 变量)的长度不一致,我不知道如何规避这个错误。任何想法都非常感谢。reduce2
.x
.y
#Produces error
out_dat <- in_dat %>%
bind_cols(map2_dfc(
.x = in_dat %>% select(starts_with('x')),
.y = in_dat %>% select(starts_with('y')),
.f = ~if_else(is.na(.x) & is.na(.y), TRUE, FALSE)
))
Error: Mapped vectors must have consistent lengths:
* `.x` has length 4
* `.y` has length 6
解决方案
这是使用lapply
,sapply
和创建数据框的简短基本 R 方法mapply
:
all_cols <- lapply(in_dat, function(y) sapply(in_dat, function(x) is.na(y) & is.na(x)))
all_cols <- mapply(function(x, y) {colnames(x) <- paste(y, colnames(x), sep = "_"); x},
all_cols, names(all_cols), SIMPLIFY = FALSE)
df <- as_tibble(cbind(in_dat, do.call(cbind, all_cols)))
df
#> # A tibble: 1,000 x 110
#> x1 x2 x3 x4 y1 y2 y3 y4 y5 y6 x1_x1 x1_x2 x1_x3 x1_x4
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <lgl> <lgl> <lgl> <lgl>
#> 1 3 7 2 5 1 1 0 1 0 NA FALSE FALSE FALSE FALSE
#> 2 7 5 10 3 NA 0 NA NA 0 NA FALSE FALSE FALSE FALSE
#> 3 3 3 3 7 1 1 NA 1 1 1 FALSE FALSE FALSE FALSE
#> 4 7 3 1 8 1 NA 1 0 NA 1 FALSE FALSE FALSE FALSE
#> 5 5 2 10 7 0 NA NA 0 NA 1 FALSE FALSE FALSE FALSE
#> 6 7 8 10 8 NA 1 1 1 1 1 FALSE FALSE FALSE FALSE
#> 7 10 8 3 5 0 1 NA 1 1 1 FALSE FALSE FALSE FALSE
#> 8 1 10 5 10 1 NA NA 0 1 1 FALSE FALSE FALSE FALSE
#> 9 7 2 5 9 NA 0 0 NA 1 1 FALSE FALSE FALSE FALSE
#> 10 8 9 1 4 1 NA NA 1 NA 0 FALSE FALSE FALSE FALSE
#> # ... with 990 more rows, and 96 more variables
唯一的问题是您还检查了每一行,因此要删除它们,您可以执行以下操作:
df <- df[sapply(strsplit(names(df), "_"), function(x) {!any(duplicated(x))})]
推荐阅读
- azure-application-insights - Application Insights - 无法查看 SQL 查询
- android - 导航架构组件 - 启动画面
- svg - 在 Scala.js 中,修改 svg.Stylable.style
- apache - 是否可以将子目录指向另一个 AWS 实例?
- java - Jersey 端点在 Eclipse 上返回 404
- amazon-web-services - aws cli s3 存储桶下载命令错误
- yii2 - 使用 Yii2 进行评分系统验证
- c# - 针对我的案例进行代码重构
- php - Wordpress - 权限被拒绝
- javascript - Android webview 显示旧网站内容而不是新网站内容