我想使用dplyr::coalesce在包含多对变量的数据文件中找到变量对之间的第一个不丢失的值。目标是创建一个新的dataframe,现在每个变量只有一个副本(一个没有NA值的合并变量)。
下面是一个示例:
df <- data.frame(
A_1=c(NA, NA, 3, 4, 5),
A_2=c(1, 2, NA, NA, NA),
B_1=c(NA, NA, 13, 14, 15),
B_2=c(11, 12, NA, NA, NA))
Expected output:
A B
1 11
2 12
3 13
4 14
5 15我猜想可以使用dplyr::coalesce与基于正则表达式的dplyr::mutate_at混合使用,但我不知道该如何做。有没有办法用tidyverse语法来完成这个任务?
谢谢!
编辑:谢谢大家的回答!然而,我应该为我的变量加上命名约定,以便于您对我的实际问题的回答。对此我很抱歉。我的变量是在两个部分中命名的地球化学变量(化学元素名称和核心名称)。
示例:Al_TAC4.25.275,其中Al是元素,TAC4.25.275是核心。我想为每个元素(名称的第一部分)合并来自3个不同核心(名称的第二部分)的数据。我有25对元素要结合。
发布于 2021-12-21 22:57:22
这是另一个更简洁的解决方案,与我的另一个方案相比。我认为cur_data()函数的使用非常有用,但您也可以使用across(everything())来代替它:
library(dplyr)
library(purrr)
unique(sub("(\\D)_\\d+", "\\1", names(df))) %>%
map_dfc(~ df %>%
select(starts_with(.x)) %>%
summarise(!!.x := do.call(coalesce, cur_data())))
A B
1 1 11
2 2 12
3 3 13
4 4 14
5 5 15这是对尽可能多的对的另一个解决方案。请注意,我使用了bang bang运算符(!!!),以便将数据帧的元素折叠为独立的单个参数,以便将coalesce应用于它们:
library(dplyr)
library(rlang)
as.data.frame(do.call(cbind, lapply(split.default(df, sub("(\\D)_\\d+", "\\1", names(df))), function(x) {
coalesce(!!!x)
})))
A B
1 1 11
2 2 12
3 3 13
4 4 14
5 5 15发布于 2021-12-21 22:49:36
基本R选项
list2DF(
lapply(
split.default(df, gsub("_.*", "", names(df))),
rowSums,
na.rm = TRUE
)
)给出
A B
1 1 11
2 2 12
3 3 13
4 4 14
5 5 15发布于 2021-12-21 22:56:06
这里有另一种选择,即旋转:
library(dplyr)
library(tidyr)
df %>%
pivot_longer(
everything()
) %>%
mutate(name = substr(name, 1, 1)) %>%
na.omit %>%
pivot_wider(
names_from = name,
values_from = value,
values_fn = list
) %>%
unnest(cols = c(A, B)) A B
<dbl> <dbl>
1 1 11
2 2 12
3 3 13
4 4 14
5 5 15https://stackoverflow.com/questions/70442283
复制相似问题