通过自定义函数在循环中创建一个新的均值列

Creating a new mean column in a loop by a custom function

我希望在每次调用分组均值函数时为所有因子数据类型创建一个新列。

我只能复制决策结果,但只能复制单个因子变量 A

   df <- data.frame(
      target = c(1, 4, 8, 9, 2, 1, 3, 5, 7, 1),
      A = c("A", "Z", "N", "A", "Z"),
      B = c("B", "Q", "G", "B", "T"),
      C = c("C", "Y", "C", "P", "Y")
    )

grouped_mean <- function(data, summary_var, ...) {
  summary_var <- enquo(summary_var)

  data %>%
    # Selects only factor data types and a target column
    select(which(map_chr(., class) == "factor"), !!summary_var) %>%
    group_by(...) %>%
    # Over here I am not able to change column name, so that it yields Mean_A, Mean_B and Mean_C
    mutate(mean = mean(!!summary_var)) %>%
    ungroup()
}

grouped_mean(data = df, 
             group_var = A, 
             summary_var = target)

我试过循环:

map_df(df, grouped_mean(data = df, summary_var = target))

但是我得到这个错误:

Error: Can't convert a tbl_df/tbl/data.frame object to function

问题和意见:

  1. 我不确定如何创建动态更改名称的函数 在 mutate 函数中,从名称 meanmean_Amean_Bmean_c
  2. 我尝试使用 map_df 函数来循环 df 的每个元素,但没有成功。这个想法是创建新的列,这些列是目标特征的平均值。

这是一个有点古怪的解决方案,但它应该适合您(假设您可以将 target 指定为您想要的平均值的列)。这只是使用 mutate_if() 并使用 tapply() 的子集来获得你的手段。

然后,它使用 rename_at() 更改名称以匹配您想要的输出。如果你希望它是小写的,你可以用 tolower()

包裹 gsub()
df %>%
  mutate_if(is.factor, list(Mean = ~tapply(df$target, ., mean)[.])) %>%
  rename_at(vars(ends_with("Mean")), ~gsub("(.*?)_(.*)", "\2_\1", .))

   target A B C Mean_A Mean_B Mean_C
1       1 A B C    4.5    4.5   3.75
2       4 Z Q Y    2.5    3.5   2.50
3       8 N G C    6.5    6.5   3.75
4       9 A B P    4.5    4.5   8.00
5       2 Z T Y    2.5    1.5   2.50
6       1 A B C    4.5    4.5   3.75
7       3 Z Q Y    2.5    3.5   2.50
8       5 N G C    6.5    6.5   3.75
9       7 A B P    4.5    4.5   8.00
10      1 Z T Y    2.5    1.5   2.50