繁体   English   中英

有没有办法在 R 中的数据间隙之间对列中的值进行分组?

[英]Is there a way to group values in a column between data gaps in R?

当数据是连续的时,我想将我的数据分组到不同的块中。 试图从这样的虚拟数据中获取组列:

       a     b group
   <dbl> <dbl> <dbl>
 1     1     1     1
 2     2     2     1
 3     3     3     1
 4     4    NA    NA
 5     5    NA    NA
 6     6    NA    NA
 7     7    12     2
 8     8    15     2
 9     9    NA    NA
10    10    25     3

我尝试使用

test %>% mutate(test = complete.cases(.)) %>%
  group_by(group = cumsum(test == TRUE)) %>%
  select(group, everything())

但它没有按预期工作:

   group     a     b test 
   <int> <dbl> <dbl> <lgl>
 1     1     1     1 TRUE 
 2     2     2     2 TRUE 
 3     3     3     3 TRUE 
 4     3     4    NA FALSE
 5     3     5    NA FALSE
 6     3     6    NA FALSE
 7     4     7    12 TRUE 
 8     5     8    15 TRUE 
 9     5     9    NA FALSE
10     6    10    25 TRUE 

有什么建议吗?

在基 R 中使用rle -

transform(df, group1 = with(rle(!is.na(b)), rep(cumsum(values), lengths))) |>
  transform(group1 = replace(group1, is.na(b), NA))

#    a  b group group1
#1   1  1     1      1
#2   2  2     1      1
#3   3  3     1      1
#4   4 NA    NA     NA
#5   5 NA    NA     NA
#6   6 NA    NA     NA
#7   7 12     2      2
#8   8 15     2      2
#9   9 NA    NA     NA
#10 10 25     3      3 

如果您希望为此使用dplyr ,可以考虑几种方法。

首先,您可以查看从非完整案例(使用lag )到完整案例的过渡。

library(dplyr)

test %>% 
  mutate(test = complete.cases(.)) %>%
  group_by(group = cumsum(test & !lag(test, default = F))) %>%
  mutate(group = replace(group, !test, NA))

或者,您可以向 data.frame 添加行号。 然后,您可以过滤以仅包含完整的案例,并根据行号中的差距使用cumsum枚举group_by 然后,连接回原始数据。

test$rn <- seq.int(nrow(test))

test %>% 
  filter(complete.cases(.)) %>%
  group_by(group = c(0, cumsum(diff(rn) > 1)) + 1) %>%
  right_join(test) %>%
  arrange(rn) %>%
  dplyr::select(-rn)

输出

       a     b group
   <int> <int> <dbl>
 1     1     1     1
 2     2     2     1
 3     3     3     1
 4     4    NA    NA
 5     5    NA    NA
 6     6    NA    NA
 7     7    12     2
 8     8    15     2
 9     9    NA    NA
10    10    25     3

使用data.table ,获取rleid然后删除 NA 的组 ID,然后使用因子整数转换修复序列:

library(data.table)

setDT(test)[, group1 := {
  x <- complete.cases(test)
  grp <- rleid(x)
  grp[ !x ] <- NA
  as.integer(factor(grp))
  }]
#      a  b group group1
#  1:  1  1     1      1
#  2:  2  2     1      1
#  3:  3  3     1      1
#  4:  4 NA    NA     NA
#  5:  5 NA    NA     NA
#  6:  6 NA    NA     NA
#  7:  7 12     2      2
#  8:  8 15     2      2
#  9:  9 NA    NA     NA
# 10: 10 25     3      3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM