R 随着时间的推移等于模式(按组)的分组观察数

R number of grouped observations equal to the mode (by group) over time

我正在查看分组数据中值 X 随时间 (t) 的变化情况。对于大多数观察结果,X 从零开始,然后随着时间的推移随机变化。在每个时间点,我想找出每个组有多少观察值具有该组的 mode 值 - 理想情况下不包括零值。数据如下所示,但有更多、更大的组和更多的 t 列。

     group_name t1 t10 t50 t100
1            s3  0 259 187  122
2            s1 29  25  23   15
3            s3  0 259  23  122
4            s2  0  36  24   15
5            s1 29  25  23   15
6            s2  0  32  24   15

最终,我想绘制有多少观测值具有各自组的模式值作为 t 的函数,但我不知道如何使用高效的 R 代码处理数据。

我看到有几种方法可以计算每个组在单个时间点的模式(例如 ),但我不知道如何调整这些方法来计算等于那个模式,或者哪个是扩展多个 t 列的最有效方法。

感谢任何建议!

我们可以通过在子集上应用 Mode 函数,按 'group_name' 和 summarise across 其余列 (everything()) 进行分组通过排除 0 值 (.[. != 0]) 的行数,使用列的元素创建一个逻辑向量 (==) 并获取 sum 以通过分组找到每列的频率变量

library(dplyr)
df1 %>%
    group_by(group_name) %>%
    summarise(across(everything(), ~ sum(Mode(.[. !=0]) == ., na.rm = TRUE)))
# A tibble: 3 x 5
#  group_name    t1   t10   t50  t100
#  <chr>      <int> <int> <int> <int>
#1 s1             2     2     2     2
#2 s2             0     1     2     2
#3 s3             0     2     1     2

或使用data.table

library(data.table)
setDT(df1)[, lapply(.SD, function(x) sum(Mode(x[x != 0]) == x, na.rm = TRUE)),
             by = group_name]

哪里

Mode <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

如果我们需要跨 't' 列进行计算,请重塑为 'long' 格式 (pivot_longer),filter 出 0 个值,按 [=35 分组=]、summarise 的频率为 'Mode' 个值

library(tidyr)
df1 %>% 
  pivot_longer(cols = starts_with('t')) %>%
  filter(value != 0) %>% 
  group_by(group_name) %>% 
  summarise(n_Mode = sum(Mode(value) == value))