r - 根据R中不同的运行长度替换连续的重复值
问题描述
考虑以下数据集:
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。如果 AB 的连续重复长于 1 则将所有值返回给 NA,如果 AC 的连续重复长于 2 则将所有值返回给 NA,如果 AD 的连续重复长于 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)
, thenrle()
或 data.table's的一些组合来完成,然后rleid()
根据值和使用 case_when 的运行长度有条件地将值转回 NA (我考虑过ifelse()
,但我的条件比示例中提供的要多得多,并且已阅读 case_when 将是一个更好的选择),但我无法弄清楚如何编写精确的代码来执行此操作。我遇到的一个类似问题是将 NA 替换为具有限制的先前值,但是,它是我需要做的更简单的版本。
任何建议将不胜感激。我觉得我很接近,但我需要帮助才能达到预期的结果。
解决方案
你可以做什么:
myfun <- function(x){
y <- rle(x)
z <- match(y$values, LETTERS)
ind <- which(is.na(z))
m <- z[ind + 1] - z[ind - 1] >= y$lengths[ind]
y$values[ind[m]] <- paste(y$values[ind[m] - 1], y$values[ind[m] + 1], sep = "-")
inverse.rle(y)
}
transform(dat, var1 = ave(var1, id, FUN = myfun))
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
推荐阅读
- python - How to add occurrence of each entry to pandas data frame?
- android - 如何制作,复制文本并点击浮动图标以像谷歌翻译一样进行翻译?
- javascript - forEachLoop 中的 React-native setState
- java - 如何解决 icalendar 导入时的 ParserException?
- javascript - 点击“加载更多”后,我无法顺利转移到获取图片的开头
- c# - 如何将 Automapper 与 Object in Object 一起使用
- linux - 线程控制块和线程本地存储的区别以及哪一个包含__stack_chk_guard变量
- r - 使用 PNG/JPEG 图像创建多面板图
- eclipse - EGit 多分支问题
- sql - SQL 不正确结束失败