根据R中的不同运行长度替换连续重复值
考虑以下数据集:根据R中的不同运行长度替换连续重复值,r,dplyr,group-by,mutate,rle,R,Dplyr,Group By,Mutate,Rle,考虑以下数据集: 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&quo
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
这导致:
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列分组)将其他值返回NA。如果A-B的连续重复长于1,则将所有值返回NA;如果A-C的连续重复长于2,则将所有值返回NA;如果A-D的连续重复长于3,则将所有值返回NA
我期望的结果是:
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\u by(id)
,然后是rle()
或data.table的rleid()
,然后在(我考虑ifelse()时,基于case\u的值和运行长度有条件地将值返回NA来实现
但我有比示例中提供的条件多得多的条件,并且已经阅读了该案例(如果是更好的选择),但我还无法找到如何编写精确的代码来实现这一点。然而,我遇到的一个类似问题是,这是我需要做的一个简单得多的版本
如有任何建议,将不胜感激。我觉得我离目标很近,但我需要帮助才能达到所需的结果。首先,我强烈建议使用
replace\u na
功能
然后您可以像这样使用smth:
x%
分组依据(X1)%>%
突变(X3=ifelse(X2==lag(X2,默认值=)| X2==lead(X2,默认值=),
X2,NA_整数(n))%>%
分组依据(X1,X3)%>%
突变(X4=n())
输入:
X1 X2
1 1 0
2 1 1
3 1 2
4 2 3
5 2 4
6 2 4
7 3 5
8 3 5
9 3 5
输出:
# A tibble: 9 x 4
# Groups: X1, X3 [4]
X1 X2 X3 X4
<dbl> <dbl> <dbl> <int>
1 1 0 NA 3
2 1 1 NA 3
3 1 2 NA 3
4 2 3 NA 1
5 2 4 4 2
6 2 4 4 2
7 3 5 5 3
8 3 5 5 3
9 3 5 5 3
#一个tible:9 x 4
#分组:X1,X3[4]
x1x2x3x4
1013
2 1 NA 3
3 1 2 NA 3
4 2 3 NA 1
5 2 4 4 2
6 2 4 4 2
7 3 5 5 3
8 3 5 5 3
9 3 5 5 3
然后您可以使用X4来制作您想要的东西。首先,我强烈建议您使用
replace\u na
功能
然后您可以像这样使用smth:
x%
分组依据(X1)%>%
突变(X3=ifelse(X2==lag(X2,默认值=)| X2==lead(X2,默认值=),
X2,NA_整数(n))%>%
分组依据(X1,X3)%>%
突变(X4=n())
输入:
X1 X2
1 1 0
2 1 1
3 1 2
4 2 3
5 2 4
6 2 4
7 3 5
8 3 5
9 3 5
输出:
# A tibble: 9 x 4
# Groups: X1, X3 [4]
X1 X2 X3 X4
<dbl> <dbl> <dbl> <int>
1 1 0 NA 3
2 1 1 NA 3
3 1 2 NA 3
4 2 3 NA 1
5 2 4 4 2
6 2 4 4 2
7 3 5 5 3
8 3 5 5 3
9 3 5 5 3
#一个tible:9 x 4
#分组:X1,X3[4]
x1x2x3x4
1013
2 1 NA 3
3 1 2 NA 3
4 2 3 NA 1
5 2 4 4 2
6 2 4 4 2
7 3 5 5 3
8 3 5 5 3
9 3 5 5 3
然后,您可以使用X4制作您想要的,您可以做什么:
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
myfun你能做什么:
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
myfun代码中的“值”列是什么代码中的“值”列是什么对不起,如果这是我的问题,但代码返回了一个错误“error in rle(x):“x”必须是原子类型的向量”,有什么想法吗?@el88确保将原子向量传递到函数中。不要传递列表、数据帧等签名@Onyambu。我还要解决这个错误。由于我对创建函数不熟悉,您是否介意解释一下您为m所做的计算?ie.z[ind+1]-z[ind-1]>=y$length[ind]@onyanbu我想如果你发布一个关于函数的解释会很有帮助-我对m
行也有点好奇。我的理解基本上是“如果两个字母之间的差异大于NA
的运行长度,请插入字母对”,对吗?为什么只买那对?提前感谢。@el88该行表示,如果两个字母之间的差值(如D-A(4-1)=3)大于它们之间的NA,那么这是有效的NA,可以用范围A-D替换。如果这是我的问题,很抱歉,但代码返回错误“rle(x)中的错误:'x'必须是原子类型的向量”,有什么想法吗?@el88确保你将一个原子向量传递到函数中。不要传递列表、数据帧等签名@Onyambu。我还要解决这个错误。由于我对创建函数不熟悉,您是否介意解释一下您为m所做的计算?ie.z[ind+1]-z[ind-1]>=y$length[ind]@onyanbu我想如果你发布一个关于函数的解释会很有帮助-我对m
行也有点好奇。我的理解基本上是“如果两个字母之间的差异大于NA
的运行长度,请插入字母对”,对吗?为什么只买那对?提前感谢。@el88该行表示,如果两个字母之间的差值(如D-A(4-1)=3)大于它们之间的NA,则这是有效的NA,可以用范围A-D替换。