跨列的汇总统计信息,其中列名表示组

summary stats across columns, where column names indicate groups

数据框 have 包含几千个遵循命名模式的向量。每个矢量名称都包含一个名词,然后是 _a_b_c。以下是前 10 个 vars 和 obs:

id  turtle_a   banana_a   castle_a   turtle_b   banana_b   castle_b   turtle_c   banana_c   castle_c
A      -0.58      -0.88      -0.56      -0.53      -0.32      -0.42      -0.52      -0.89      -0.72
B         NA         NA         NA      -0.84      -0.36      -0.26         NA         NA         NA
C       0.00      -0.43      -0.75      -0.35      -0.88      -0.14      -0.26      -0.15      -0.81
D      -0.81      -0.63      -0.77      -0.82      -0.83      -0.50      -0.77      -0.25      -0.07
E      -0.25      -0.33      -0.09      -0.51      -0.27      -0.81      -0.06      -0.23      -0.97
F      -0.80      -0.88      -0.05         NA         NA         NA         NA         NA         NA
G      -0.25      -0.76      -0.21         NA         NA         NA         NA         NA         NA
H      -0.47      -0.10      -0.67      -0.46      -0.71      -0.24      -0.76      -0.04      -0.11
I      -0.15      -0.34      -0.57      -0.40      -0.14      -0.49         NA         NA         NA
J      -0.65      -0.86      -0.37      -0.67      -0.81      -0.63         NA         NA         NA

数据框want是名词组中每组变量的所有列的平均值。例如,id=Aturtle_aturtle_bturtle_c 的平均值等于 -0.54。这是 want 如果我只对示例中的少数名词组执行此操作的样子。

id   turtle_m    banana_m    castle_m
A       -0.54       -0.70       -0.57
B       -0.84       -0.36       -0.26
C       -0.20       -0.49       -0.57
D       -0.80       -0.57       -0.45
E       -0.27       -0.28       -0.62
F       -0.80       -0.88       -0.05
G       -0.25       -0.76       -0.21
H       -0.56       -0.29       -0.34
I       -0.27       -0.24       -0.53
J       -0.66       -0.83       -0.50

目前的选项:

  1. 转换为长,summarize 使用 dplyr 中的 group_by() 函数,然后转置回宽。
  2. 对向量进行重新排序,使名词组彼此相邻,并编写一个循环来计算跨列的均值,每次迭代采用三列步骤

似乎 summarize_atsummarize_all 比我当前的任何一个选项都更有效,但我不确定如何以动态分组变量的方式使用它命名约定。

有什么想法吗?

我们可以使用split.default根据列名的子字符串拆分列,循环遍历listsapply,然后rowMeans然后cbind第一列

out <- cbind(df1[1], sapply(split.default(df1[-1], 
    sub("_.*", "", names(df1)[-1])), rowMeans, na.rm = TRUE))

或者我们可以使用pivot_longer

library(dplyr)
library(tidyr)
df1 %>% 
   pivot_longer(cols = -id, names_sep="_", names_to = c(".value", "group")) %>%
   group_by(id) %>%
   summarise(across(turtle:castle,  mean,  na.rm = TRUE))