我一直在尝试将mutate_at
与coalesce
结合使用,以防动态生成列名。
在我的示例中,只有五列,但是在实际数据中,则有更多列(并非所有列都应包含在coalesce
步骤中)。
DF示例:
data_example <- data.frame(
aa = c(1, NA, NA),
bb = c(NA, NA, 2),
cc = c(6, 7, 8),
aa_extra = c(2, 2, NA),
bb_extra = c(1, 2, 3)
)
预期输出:
aa bb cc aa_extra bb_extra
1 1 1 6 2 1
2 2 2 7 2 2
3 NA 2 8 NA 3
输出为structure
:
structure(list(aa = c(1, 2, NA), bb = c(1, 2, 2), cc = c(6, 7,
8), aa_extra = c(2, 2, NA), bb_extra = c(1, 2, 3)), class = "data.frame", row.names = c(NA,
-3L))
我已经尝试过类似的方法,但是没有成功(“只能将字符串转换为符号”)。我想避免创建额外的变量,只需在mutate_at
表达式中包含所有内容,因为这是较长的dplyr“流”的一部分。
data_example %>%
dplyr::mutate_at(
gsub("_extra", "", grep("_extra$",
colnames(.),
perl = T,
value = T)),
dplyr::funs(
dplyr::coalesce(., !!! dplyr::sym(paste0(., "_extra")))
)
)
我也尝试过此操作(没有错误,但是列bb
的值是错误的):
data_example %>%
dplyr::mutate_at(
gsub("_extra", "", grep("_extra$",
colnames(.),
perl = T,
value = T)),
dplyr::funs(
dplyr::coalesce(., !!as.name(paste0(names(.), "_extra")))
)
)
如何获取已处理列的名称并将其传递给coalesce
?
答案 0 :(得分:3)
在删除列名的子字符串(split
之后,我们可以list
将数据集"_extra"
放入data.frames,然后使用map
遍历{{ 1}},list
列,然后coalesce
和原始数据集中的“ _extra”列
bind
答案 1 :(得分:1)
将data.table
用于melt
和dcast
,因为我不记得spread
和gather
的工作原理
library(data.table)
library(dplyr)
data_example %>%
mutate(row = row_number()) %>%
melt('row') %>%
group_by(g = sub('_*$', '', variable), row) %>%
mutate(value = reduce(value, coalesce)) %>%
dcast(row ~ variable) %>%
select(-row)
# aa bb cc aa_extra bb_extra
# 1 1 1 6 1 1
# 2 2 2 7 2 2
# 3 NA 2 8 NA 2
答案 2 :(得分:0)
猜猜现在可以使用 mutate + across
data_example %>%
mutate(across(c(str_subset(names(.), "_extra") %>% str_remove("_extra")) ,
~ coalesce( ., get(str_c(cur_column(), "_extra")) )))
aa bb cc aa_extra bb_extra
1 1 1 6 2 1
2 2 2 7 2 2
3 NA 2 8 NA 3