我们可以在select取出相关列之后使用rowMeans
library(dplyr)
df1 %>%
mutate(NewCol1 = rowMeans(select(., -Team, -stat1), na.rm = TRUE),
NewCol2 = rowMeans(select(., -Team, -stat2), na.rm = TRUE))
-输出
# Team stat1 stat2 stat3 stat4 NewCol1 NewCol2
#1 ARI 3 NA 4 6 5.0 4.333333
#2 BAL NA 2 NA 1 1.5 1.000000
#3 CAR 5 4 6 2 4.0 4.333333
或者c_across的另一个选项
df1 %>%
rowwise %>%
mutate(NewCol1 = mean(c_across(c(where(is.numeric), -stat1)), na.rm = TRUE),
NewCol2 = mean(c_across(c(starts_with('stat'), -stat2)), na.rm = TRUE),
NewCol3 = mean(c_across(c(starts_with('stat'), -stat3)), na.rm = TRUE),
NewCol4 = mean(c_across(c(starts_with('stat'), -stat4)), na.rm = TRUE)) %>%
ungroup
-输出
# A tibble: 3 x 9
# Team stat1 stat2 stat3 stat4 NewCol1 NewCol2 NewCol3 NewCol4
# <chr> <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl>
#1 ARI 3 NA 4 6 5 4.33 4.5 3.5
#2 BAL NA 2 NA 1 1.5 1 1.5 2
#3 CAR 5 4 6 2 4 4.33 3.67 5
如果我们想自动执行此操作,可以选择
library(purrr)
df1[paste0("NewCol", 1:2)] <- map(c('stat1', 'stat2'),
~ df1 %>%
select(starts_with('stat'), -.x) %>%
rowMeans(., na.rm = TRUE))
或者创建第 1 到 4 列
nm1 <- names(df1)[startsWith(names(df1), 'stat')]
df1[paste0("NewCol", seq_along(nm1))] <- map(nm1,
~ df1 %>%
select(starts_with('stat'), -.x) %>%
rowMeans(., na.rm = TRUE))
-输出
df1
# Team stat1 stat2 stat3 stat4 NewCol1 NewCol2 NewCol3 NewCol4
#1 ARI 3 NA 4 6 5.0 4.333333 4.500000 3.5
#2 BAL NA 2 NA 1 1.5 1.000000 1.500000 2.0
#3 CAR 5 4 6 2 4.0 4.333333 3.666667 5.0
或者在 tidyverse 中完全做到这一点
library(stringr)
map_dfc(nm1, ~
df1 %>%
select(starts_with('stat'), -.x) %>%
transmute(!! str_c('NewCol', readr::parse_number(.x)) :=
rowMeans(., na.rm = TRUE))) %>%
bind_cols(df1, .)
# Team stat1 stat2 stat3 stat4 NewCol1 NewCol2 NewCol3 NewCol4
#1 ARI 3 NA 4 6 5.0 4.333333 4.500000 3.5
#2 BAL NA 2 NA 1 1.5 1.000000 1.500000 2.0
#3 CAR 5 4 6 2 4.0 4.333333 3.666667 5.0
或使用rowwise/c_across
map_dfc(nm1, ~
df1 %>%
select(starts_with('stat'), -.x) %>% rowwise %>%
transmute(!! str_c('NewCol', readr::parse_number(.x)) := mean(c_across(everything()), na.rm = TRUE))) %>%
ungroup %>%
bind_cols(df1, .)
-输出
# Team stat1 stat2 stat3 stat4 NewCol1 NewCol2 NewCol3 NewCol4
#1 ARI 3 NA 4 6 5.0 4.333333 4.500000 3.5
#2 BAL NA 2 NA 1 1.5 1.000000 1.500000 2.0
#3 CAR 5 4 6 2 4.0 4.333333 3.666667 5.0
或使用base R
df1[paste0("NewCol", seq_along(nm1))] <- lapply(nm1,
function(x) rowMeans(df1[setdiff(names(df1)[-1], x)], na.rm = TRUE))
数据
df1 <- structure(list(Team = c("ARI", "BAL", "CAR"), stat1 = c(3L, NA,
5L), stat2 = c(NA, 2L, 4L), stat3 = c(4L, NA, 6L), stat4 = c(6L,
1L, 2L)), class = "data.frame", row.names = c("1", "2", "3"))