我正在尝试为每个事件/剧集生成唯一的 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 号。
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
受到@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
与@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
这是一个
dplyr
解决方案,如果您想将平均值添加为新列而不是将行数减少到每组一个,请使用mutate
。
library(dplyr)
df %>%
group_by(ID = paste0(Event, cumsum(lag(Event, default = first(Event)) != Event) + 1)) %>%
summarize(Val = mean(Val), .groups = "drop")