我最近不得不编译学生分数的数据框(每个学生一行,id列和几个整数值列,每个分数一个)。我必须结合一个"大师"数据框和几个"校正"数据框(主要包含NA
和对主服务器的一些更新),以便结果包含主服务器的最大值和所有更正。
我成功通过复制粘贴一系列mutate()
个调用,这有效(见下面的例子),但在我看来并不优雅。我想要做的是,而不是复制和粘贴,使用map2
和两列列的内容来逐对比较列。像(显然不能这样)的东西:
list_of_cols1 <- list(col1.x, col2.x, col3.x)
list_of_cols2 <- list(col1.y, col2.y, col3.y
map2(list_of_cols1, list_of_cols2, ~ column = pmax(.x, .y, na.rm=T))
我似乎无法理解这样做。我的问题是:如何指定这样的列列表并在map2()
管道中的dplyr
调用中对其进行变更,或者甚至是可能的 - 我是否完全错了?
最低工作实例
library(tidyverse)
master <- tibble(
id=c(1,2,3),
col1=c(1,1,1),
col2=c(2,2,2),
col3=c(3,3,3)
)
correction1 <- tibble(
id=seq(1,3),
col1=c(NA, NA, 2 ),
col2=c( 1, NA, 3 ),
col3=c(NA, NA, NA)
)
result <- reduce(
# Ultimately there would several correction data frames
list(master, correction1),
function(x,y) {
x <- x %>%
left_join(
y,
by = c("id")
) %>%
# Wish I knew how to do this mutate call with map2
mutate(
col1 = pmax(col1.x, col1.y, na.rm=T),
col2 = pmax(col2.x, col2.y, na.rm=T),
col3 = pmax(col3.x, col3.y, na.rm=T)
) %>%
select(id, col1:col3)
}
)
结果是
> result
# A tibble: 3 x 4
id col1 col2 col3
<int> <dbl> <dbl> <dbl>
1 1 1 2 3
2 2 1 2 3
3 3 2 3 3
答案 0 :(得分:0)
而不是执行left_join
,只需绑定行然后进行汇总。例如
result <- reduce(
list(master, master),
function(x,y) {
bind_rows(x, y) %>%
group_by(id) %>%
summarize_all(max, na.rm=T)
}
)
result
# id col1 col2 col3
# <dbl> <dbl> <dbl> <dbl>
# 1 1 1 2 3
# 2 2 1 2 3
# 3 3 2 3 3
实际上,您甚至不需要缩减,因为bind_rows
可以列出
添加另一张表
correction2 <- tibble(id=2,col1=NA,col2=8,col3=NA)
bind_rows(master, correction1, correction2) %>%
group_by(id) %>%
summarize_all(max, na.rm=T)
答案 1 :(得分:0)
很抱歉,我们没有回答您关于map2
的问题,我发现在行上汇总比在tidy
R中的列更容易:
library(dplyr)
master <- tibble(
id=c(1,2,3),
col1=c(1,1,1),
col2=c(2,2,2),
col3=c(3,3,3)
)
correction1 <- tibble(
id=seq(1,3),
col1=c(NA, NA, 2 ),
col2=c( 1, NA, 3 ),
col3=c(NA, NA, NA)
)
result <- list(master, correction1) %>%
bind_rows() %>%
group_by(id) %>%
summarise_all(max, na.rm = TRUE)
result
#> # A tibble: 3 x 4
#> id col1 col2 col3
#> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1 2 3
#> 2 2 1 2 3
#> 3 3 2 3 3
答案 2 :(得分:0)
如果correction
表格总是与master
具有相同的结构,您可以执行以下操作:
library(dplyr)
library(purrr)
update_master = function(...){
map(list(...), as.matrix) %>%
reduce(pmax, na.rm = TRUE) %>%
data.frame()
}
update_master(master, correction1)
要允许id
获取字符值,请进行以下修改:
update_master = function(x, ...){
map(list(x, ...), function(x) as.matrix(x[-1])) %>%
reduce(pmax, na.rm = TRUE) %>%
data.frame(id = x[[1]], .)
}
update_master(master, correction1)
<强>结果:强>
id col1 col2 col3
1 1 1 2 3
2 2 1 2 3
3 3 2 3 3