随时间变化的分组观察数R等于模式按组

问题描述

我正在研究值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代码来处理数据。

我已经看到有几种方法可以在一个时间点为每个组计算模式(例如here),但是我不知道如何适应这些方法来计算等于该模式的数量,否则这将是放大多个t列的最有效方法

谢谢您的建议!

解决方法

通过对行的子集应用summarise函数,我们可以按'group_name'和across everything()分组其余的列(Mode 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个值,并按'group_name',summarise分组频率为“模式”值

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