也许是这个?
no_g <- split(names(dat), sub(".*_", "", names(dat)))
no_g
# $param1
# [1] "g1_param1" "g2_param1"
# $param2
# [1] "g1_param2" "g2_param2"
as.data.frame(
Map(function(nm, cols) do.call(dplyr::coalesce, dat[cols]), names(no_g), no_g)
)
# param1 param2
# 1 7 4
# 2 1 1
您可以更换dplyr::coalesce
with data.table::fcoalesce
或者如果你没有的话,可以使用自己开发的函数dplyr
可用的。例如,
my_coalesce <- function(...) {
dots <- list(...)
if (length(dots) == 0) return()
if (length(dots) == 1) return(dots[[1]])
out <- dots[[1]]
for (i in seq_along(dots)[-1]) {
if (!any(isna <- is.na(out))) break
out[isna] <- dots[[i]][isna]
}
out
}
(未经测试,它“应该有效”,但如果您使用经过时间验证的东西可能会更好。值得注意的是,它并没有验证所有长度dots
是相等的,因为在此操作中它们必须相等。或者它们中的任何一个都有长度。)
Data:
dat <- structure(list(g1_param1 = c(NA, 1L), g2_param1 = c(7L, NA), g1_param2 = c(NA, 1L), g2_param2 = c(4L, NA)), class = "data.frame", row.names = c(NA, -2L))