根据列创建唯一ID,并根据R中生成的ID计算均值

问题描述 投票:0回答:4

我正在尝试为每个事件/剧集生成唯一的 ID,然后想根据生成的 ID 计算列的平均值。

举个例子:

活动 瓦尔
A 3
A 5
A 1
8
2
C 1
C 3
A 2
A 5

首先, 我想创建一个 ID 列,如下所示,

活动 瓦尔 ID
A 3 A1
A 5 A1
A 1 A1
8 B1
2 B1
C 1 C1
C 3 C1
A 2 A2
A 5 A2

第二, 我想根据生成的 ID 列计算“Val”的平均值。

感谢您的帮助和建议。

我试过“cumsum”和“duplicated”功能,但往往会生成连续的 ID 号。

r dplyr uniqueidentifier
4个回答
4
投票

A

data.table
方法:

library(data.table)

DT <- data.table(
    Event = c("A", "A", "A", "B", "B", "C", "C", "A", "A"),
    Val = c(3L, 5L, 1L, 8L, 2L, 1L, 3L, 2L, 5L)
  )

DT[, ID := rleid(Event)][, ID := rleid(ID), by = Event][, ID := paste0(Event, ID)][, mean := mean(Val), by = ID]

> DT
   Event Val ID mean
1:     A   3 A1  3.0
2:     A   5 A1  3.0
3:     A   1 A1  3.0
4:     B   8 B1  5.0
5:     B   2 B1  5.0
6:     C   1 C1  2.0
7:     C   3 C1  2.0
8:     A   2 A2  3.5
9:     A   5 A2  3.5

3
投票

受到@ismirsehregal 的解决方案的启发,这里有一个 dplyr 版本:

library(dplyr)

df %>% 
    group_by(Event) %>%
    mutate(ID = paste0(Event, cumsum(c(TRUE, diff(Val != lag(Val, default = first(Val))) != 0)))) %>%
    group_by(Event, ID) %>%
    mutate(mean = mean(Val)) %>%
    ungroup()

 Event   Val ID     mean
  <chr> <int> <chr> <dbl>
1 A         3 A1     3   
2 A         5 A2     3.25
3 A         1 A2     3.25
4 B         8 B1     8   
5 B         2 B2     2   
6 C         1 C1     1   
7 C         3 C2     3   
8 A         2 A2     3.25
9 A         5 A2     3.25

3
投票

与@ismirsehregal 类似的方法,但带有

dplyr
。请注意,
consecutive_id
是在最新的 dplyr 更新
dplyr 1.1.0
中引入的。

library(dplyr) #1.1.0+ 
df %>% 
  mutate(id = consecutive_id(Event)) %>% 
  mutate(id = paste0(Event, consecutive_id(id)), .by = Event) %>%
  mutate(mean = mean(Val), .by = id)

  Event Val id mean
1     A   3 A1  3.0
2     A   5 A1  3.0
3     A   1 A1  3.0
4     B   8 B1  5.0
5     B   2 B1  5.0
6     C   1 C1  2.0
7     C   3 C1  2.0
8     A   2 A2  3.5
9     A   5 A2  3.5

1
投票

这是一个

dplyr
解决方案,如果您想将平均值添加为新列而不是将行数减少到每组一个,请使用
mutate

library(dplyr)
  
df %>% 
  group_by(ID = paste0(Event, cumsum(lag(Event, default = first(Event)) != Event) + 1)) %>% 
  summarize(Val = mean(Val), .groups = "drop")
© www.soinside.com 2019 - 2024. All rights reserved.