[英]How to compress/delete rows with conditions in R?
我有一个数据框,请看下面。 如何在某些条件下压缩/删除行? 我想选择最高音量,只有V1连续1
例如: df[2:5,]
的V1
都等于1
,其中最高音量为df[4,]
所以删除df[c(2,3,5),]
为df[9:10,]
,最高音量这两个是df[10,]
,删除df[9,]
.....等......结果将像示例图片 ,其中V1
将像0101010101 ....
如何在不使用循环的情况下实现这一点,如何实现矢量化方式,以便计算速度更快(处理数百万行时)?
更新:我对V2
应用相同的循环,但仅在Volume较小时才删除,这就是为什么在示例图片中删除了第13行,因为第13行的音量小于第14行的音量。
更新(另一个问题):我尝试过akrun的方法,我从组中选择最大Volume
,但是当有两个或更多的最大值时,仍然会有一个连续的1
,就像row 9
一样。 如何删除重复的行? 我可以使用duplicated(df$Volume)
,还有另一种方法吗? 谢谢
更新:跟进akrun的尝试,代码将删除V1==0
的行,这不是我所追求的,我只想在V1==1
且卷小于最大卷的时候删除组。 我知道这将有一些连续0 V1
,并删除重复的0 V1
将取决于Weight
所以这就是为什么我需要删除V1==1
仅供参考,不能删除V1==0
# Volume Weight V1 V2
#1 0.5367 0.5367 0 1
#4 1.1457 1.1413 1 0
#6 0.5694 0.5633 0 1
#7 1.2368 1.2343 1 0
#8 0.9662 0.9593 0 1
#9 1.4102 1.3923 1 0
#10 1.4102 1.3995 1 0
#11 1.1132 1.1069 0 1
#12 1.4535 1.3923 1 0
#14 1.1475 1.1447 0 1
#15 1.1790 1.1748 1 0
#18 1.1557 1.1552 0 1
数据帧df
Volume Weight V1 V2
1: 0.5367 0.5367 0 1
2: 0.8645 0.8508 1 0
3: 0.8590 0.8585 1 0
4: 1.1457 1.1413 1 0
5: 0.8573 0.8568 1 0
6: 0.5694 0.5633 0 1
7: 1.2368 1.2343 1 0
8: 0.9662 0.9593 0 1
9: 1.3550 1.3412 1 0
10: 1.4102 1.3995 1 0
11: 1.1132 1.1069 0 1
12: 1.4535 1.3923 1 0
13: 1.0437 1.0344 0 1
14: 1.1475 1.1447 0 1
15: 1.1790 1.1748 1 0
16: 1.1749 1.1735 1 0
17: 1.1749 1.1731 1 0
18: 1.1557 1.1552 0 1
示例图片
Volume Weight V1 V2
1: 0.5367 0.5367 0 1
4: 1.1457 1.1413 1 0
6: 0.5694 0.5633 0 1
7: 1.2368 1.2343 1 0
8: 0.9662 0.9593 0 1
10: 1.4102 1.3995 1 0
11: 1.1132 1.1069 0 1
12: 1.4535 1.3923 1 0
14: 1.1475 1.1447 0 1
15: 1.1790 1.1748 1 0
18: 1.1557 1.1552 0 1
你可以使用library(data.table)
:
setDT(df)[, .SD[(Volume == max(Volume) & V1 == 1) | V1 != 0], by = rleid(df$V1)][]
编辑:
关于列丢弃问题,来自akrun的改编技巧:
setDT(df)[df[, .I[(Volume == max(Volume) & V1 == 1) | V1 == 0], rleid(V1)]$V1][]
我们可以使用base R
rle
grp <- inverse.rle(within.list(rle(df$V1), values <- seq_along(values)))
df[with(df, ave(Volume, grp, FUN = max)==Volume),]
# Volume Weight V1 V2
#1 0.5367 0.5367 0 1
#4 1.1457 1.1413 1 0
#6 0.5694 0.5633 0 1
#7 1.2368 1.2343 1 0
#8 0.9662 0.9593 0 1
#10 1.4102 1.3995 1 0
#11 1.1132 1.1069 0 1
#12 1.4535 1.3923 1 0
#14 1.1475 1.1447 0 1
#15 1.1790 1.1748 1 0
#18 1.1557 1.1552 0 1
注意:我们使用data.frame
而不是data.table
作为输入数据
或者,您可以尝试使用tidyverse
函数。
考虑将dftest
作为初始数据帧,标记连续组:
dftest$f1 <- ifelse(x <- dftest$V1 == 1, cumsum(c(head(x, 1), tail(x, -1) - head(x, -1) == 1)), NA)
dftest$f2 <- ifelse(x <- dftest$V2 == 1, cumsum(c(head(x, 1), tail(x, -1) - head(x, -1) == 1)), NA)
然后对这些群体进行操作:
dftest %>%
group_by(f1) %>%
filter( if_else(is.na(f1), Volume == Volume, Volume == max(Volume))) %>%
ungroup() %>%
group_by(f2) %>%
filter( if_else(is.na(f2), Volume == Volume, Volume == max(Volume)))
这使:
Source: local data frame [11 x 6]
Groups: f2 [7]
Volume Weight V1 V2 f1 f2
<dbl> <dbl> <int> <int> <int> <int>
1 0.5367 0.5367 0 1 NA 1
2 1.1457 1.1413 1 0 1 NA
3 0.5694 0.5633 0 1 NA 2
4 1.2368 1.2343 1 0 2 NA
5 0.9662 0.9593 0 1 NA 3
6 1.4102 1.3995 1 0 3 NA
7 1.1132 1.1069 0 1 NA 4
8 1.4535 1.3923 1 0 4 NA
9 1.1475 1.1447 0 1 NA 5
10 1.1790 1.1748 1 0 5 NA
11 1.1557 1.1552 0 1 NA 6
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.