【发布时间】:2020-11-10 22:24:14
【问题描述】:
考虑以下数据集:
dat<-data.frame(id = c(1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3),
var1 = c("A","NA","B","A","NA","NA","B","A","NA","NA","NA","C","A","NA","B","A","NA","NA","D","A","NA","NA","B"))
dat
首先,我需要用 NA 两侧的值填写所有 NA,这在 dplyr 中是成功的:
mutate(value = ifelse(is.na(value), paste0(na.locf(value), "-", na.locf(value, fromLast=TRUE)),
value))
这导致:
id var1
1 1 A
2 1 A-B
3 1 B
4 1 A
5 1 A-B
6 1 A-B
7 1 B
8 2 A
9 2 A-C
10 2 A-C
11 2 A-C
12 2 C
13 2 A
14 2 A-B
15 2 B
16 3 A
17 3 A-D
18 3 A-D
19 3 D
20 3 A
21 3 A-B
22 3 A-B
23 3 B
但是,我现在需要根据重复的连续运行长度(按 id col 分组)保留一些值,同时将其他值返回 NA。如果 A-B 连续重复长于 1 则返回所有值到 NA,如果 A-C 连续重复长于 2 则返回所有值到 NA,如果 A-D 连续重复长于 3 则返回所有值到北美。
我想要的结果是:
id var1
1 1 A
2 1 A-B
3 1 B
4 1 A
5 1 NA
6 1 NA
7 1 B
8 2 A
9 2 NA
10 2 NA
11 2 NA
12 2 C
13 2 A
14 2 A-B
15 2 B
16 3 A
17 3 A-D
18 3 A-D
19 3 D
20 3 A
21 3 NA
22 3 NA
23 3 B
我认为这可以通过group_by(id)、rle() 或 data.table 的rleid() 的组合来实现,然后根据值和运行长度有条件地将值转回 NA 与 case_when(我考虑过ifelse() 但我的条件比示例中提供的要多得多,并且已经阅读了 case_when 会是更好的选择),但我无法弄清楚如何编写精确的代码来执行此操作。我遇到的一个类似问题是Replace NA with previous value with limit,但它是我需要做的更简单的版本。
任何建议将不胜感激。我觉得我很接近了,但我需要帮助才能达到预期的结果。
【问题讨论】:
-
代码中的“值”列是什么