【问题标题】:Summarising series of 1 and 0 in a dataframe in R在R中的数据框中总结1和0的系列
【发布时间】:2020-02-04 11:30:39
【问题描述】:
我想编写一个 R 代码来总结数据框中的 1 和 0 序列(基本上我需要将运行长度编码应用于列“值”),但我需要保留有关列“ID”的信息.
这是需要总结的数据框示例:
> df
ID Values
1 1 0
2 2 0
3 3 0
4 4 1
5 5 1
6 6 1
7 7 1
8 8 0
9 9 0
10 10 0
11 11 1
12 12 0
13 13 0
14 14 1
15 15 0
16 16 0
这是预期的输出:
> df
ID lengths values
1 1 3 0
2 4 4 1
3 8 3 0
4 11 1 1
5 12 2 0
6 14 1 1
7 15 2 0
有人可以帮我高效地写这个吗?
谢谢!
【问题讨论】:
标签:
r
dataframe
run-length-encoding
【解决方案1】:
您可以使用 data.table 的分组和rleid 函数轻松做到这一点:
library(data.table)
setDT(df)
df[, .(ID = ID[1], lengths = .N, values = Values[1]), by = rleid(Values)]
# rleid ID lengths values
#1: 1 1 3 0
#2: 2 4 4 1
#3: 3 8 3 0
#4: 4 11 1 1
#5: 5 12 2 0
#6: 6 14 1 1
#7: 7 15 2 0
【解决方案2】:
library(tidyverse)
df %>%
group_by(group = cumsum(Values != lag(Values, default = first(Values)))) %>%
summarise(ID = min(ID),
lengths = n(),
values = unique(Values)) %>%
select(-group)
# # A tibble: 7 x 3
# ID lengths values
# <int> <int> <int>
# 1 1 3 0
# 2 4 4 1
# 3 8 3 0
# 4 11 1 1
# 5 12 2 0
# 6 14 1 1
# 7 15 2 0
【解决方案3】:
这里是一个基于 R 的解决方案:
r <- rle(df$Values)
data.frame(ID=df$ID[1+cumsum(c(0, head(r$lengths, -1)))], r$lengths, r$values)
# > data.frame(ID=df$ID[1+cumsum(c(0, head(r$lengths, -1)))], r$lengths, r$values)
# ID r.lengths r.values
# 1 1 3 0
# 2 4 4 1
# 3 8 3 0
# 4 11 1 1
# 5 12 2 0
# 6 14 1 1
# 7 15 2 0
【解决方案4】:
另一个dplyrversion,可能更容易理解:
df %>%
mutate(doesValueChange = Values - lag(Values) != 0) %>%
mutate(doesValueChange = replace_na(doesValueChange, FALSE)) %>%
mutate(sequenceNr = cumsum(doesValueChange)) %>%
group_by(sequenceNr) %>%
summarise(ID = first(ID)
, lengths = n()
, Values = first(Values))