r - 按名称将 tibble 列映射到另一列
问题描述
我有一个字符列,field_name
其中包含其他列的名称。我想创建另一列,field_value
,它将包含基于field_name
每一行的值。如果field_name
是 NA,field_value
也应该是 NA。我对使用不感兴趣rowwise()
(出于性能原因)。
# A tibble: 3 × 6
category stage is_solid saturation is_vaccinated field_name
<chr> <chr> <lgl> <dbl> <lgl> <chr>
1 oncology I TRUE NA TRUE stage
2 covid19 NA NA 95 FALSE saturation
3 other NA NA NA TRUE NA
预期结果:
# A tibble: 3 × 7
category stage is_solid saturation is_vaccinated field_name field_value
<chr> <chr> <lgl> <dbl> <lgl> <chr> <chr>
1 oncology I TRUE NA TRUE stage I
2 covid19 NA NA 95 FALSE saturation 95
3 other NA NA NA TRUE NA NA
df <-
tibble(
stringsAsFactors = FALSE,
category = c("oncology", "covid19", "other"),
stage = c("I", NA, NA),
is_solid = c(TRUE, NA, NA),
saturation = c(NA, 95, NA),
is_vaccinated = c(TRUE, FALSE, TRUE),
field_name = c("stage", "saturation", NA)
)
更新:当我们在阶段有其他值时,@deschen 的答案不起作用。例如,
df <-
tibble(
stringsAsFactors = FALSE,
category = c("oncology", "covid19", "other"),
stage = c("I", "II", "III"),
is_solid = c(TRUE, NA, NA),
saturation = c(NA, 95, NA),
is_vaccinated = c(TRUE, FALSE, TRUE),
field_name = c("stage", "saturation", NA)
)
解决方案
您可以将field_name
值作为字符向量传递across
,将其转换为字符值,然后使用coalesce
将几个新生成的列合并为一个。注意,由于coalese
还不能正常工作across
,我们必须使用do.call
. 这可能会在某个时候改变。
另请注意,您可能希望确保对临时列使用真正唯一的命名模式,以免在此过程中干扰任何潜在的现有列。
尽管您排除了rowwise
解决方案,但我会对它的外观非常感兴趣。我猜下面的解决方案在数量级上不会比rowwise
.
library(tidyverse)
df %>%
mutate(across(all_of(na.omit(df$field_name)), ~as.character(.), .names = "{.col}_temp"),
field_value = do.call(coalesce, across(ends_with("_temp")))) %>%
select(-ends_with("_temp"))
这使:
# A tibble: 3 x 7
category stage is_solid saturation is_vaccinated field_name field_value
<chr> <chr> <lgl> <dbl> <lgl> <chr> <chr>
1 oncology I TRUE NA TRUE stage I
2 covid19 <NA> NA 95 FALSE saturation 95
3 other <NA> NA NA TRUE <NA> <NA>
根据 TO 的新数据示例进行更新。现在涉及更多,可以通过pivot_longer/wider
往返来完成。
df %>%
mutate(across(all_of(na.omit(df$field_name)), ~as.character(.), .names = "{.col}_temp")) %>%
pivot_longer(cols = ends_with("_temp")) %>%
filter(str_detect(name, field_name) | (is.na(field_name) & is.na(value))) %>%
pivot_wider() %>%
mutate(field_value = do.call(coalesce, across(ends_with("_temp")))) %>%
select(-ends_with("_temp"))
这使:
# A tibble: 3 x 7
category stage is_solid saturation is_vaccinated field_name field_value
<chr> <chr> <lgl> <dbl> <lgl> <chr> <chr>
1 oncology I TRUE NA TRUE stage I
2 covid19 II NA 95 FALSE saturation 95
3 other III NA NA TRUE NA NA
推荐阅读
- hadoop - 在 hadoop 上使用 ORC 进行内存管理
- javascript - 如果在前端付款时数据库出错怎么办
- javascript - 如何使用javascript仅更改所选选项的背景颜色?
- c# - 对象引用未设置为对象的实例在尝试借助数据库更新数据时
- r - 如何使用 ggplot 显示截断的误差线?
- javascript - 如何将边框应用于画布上的透明图像?
- tensorflow - Keras tensorflow后端修改损失
- wso2-am - 在 WSO2 API Manager 的内置产品端点上启用 OAUTH,例如 /services/echo、/services/Version 和 /services/WorkflowCallbackService
- cntk - 获取参数数据的类型 Tensor[3,850,850] 与 cntk 上传递的变量的类型 Tensor[3,370,1224] 不兼容
- libgdx - 我在 Libgdx 中使用 Bullet Physics 来模拟软体,但软体不与重力发生反应,只是落在 -y 方向