簡體   English   中英

在R中對行進行有序分組

[英]ordered grouping of rows in R

我想創建一個新列,按順序標記行組。 原始數據:

> dt = data.table(index=(1:10), group = c("apple","apple","orange","orange","orange","orange","apple","apple","orange","apple"))
> dt
    index  group
 1:     1  apple
 2:     2  apple
 3:     3 orange
 4:     4 orange
 5:     5 orange
 6:     6 orange
 7:     7  apple
 8:     8  apple
 9:     9 orange
10:    10  apple

期望的輸出:

    index  group id
 1:     1  apple  1
 2:     2  apple  1
 3:     3 orange  1
 4:     4 orange  1
 5:     5 orange  1
 6:     6 orange  1
 7:     7  apple  2
 8:     8  apple  2
 9:     9 orange  2
10:    10  apple  3

dplyr嘗試:

dt %>% group_by(group) %>% mutate( id= row_number())
# A tibble: 10 x 3
# Groups:   group [2]
   index group     id
   <int> <chr>  <int>
 1     1 apple      1
 2     2 apple      2
 3     3 orange     1
 4     4 orange     2
 5     5 orange     3
 6     6 orange     4
 7     7 apple      3
 8     8 apple      4
 9     9 orange     5
10    10 apple      5

如何編輯這個以使第一組蘋果為1,然后第一組橙子為1,然后第二組蘋果為2等(參見上面的所需輸出)。 也對data.table解決方案開放。

library(data.table)
dt[, id := cumsum(c(TRUE, diff(index) > 1)), by="group"]
dt
#     index  group id
#  1:     1  apple  1
#  2:     2  apple  1
#  3:     3 orange  1
#  4:     4 orange  1
#  5:     5 orange  1
#  6:     6 orange  1
#  7:     7  apple  2
#  8:     8  apple  2
#  9:     9 orange  2
# 10:    10  apple  3

從原來的dt開始:

library(dplyr)
dt %>%
  group_by(group) %>%
  mutate(id = cumsum(c(TRUE, diff(index) > 1))) %>%
  ungroup()
# # A tibble: 10 x 3
#    index group     id
#    <int> <chr>  <int>
#  1     1 apple      1
#  2     2 apple      1
#  3     3 orange     1
#  4     4 orange     1
#  5     5 orange     1
#  6     6 orange     1
#  7     7 apple      2
#  8     8 apple      2
#  9     9 orange     2
# 10    10 apple      3

基地R,也許有點笨重:

out <- do.call(rbind, by(dt, dt$group,
                         function(x) transform(x, id = cumsum(c(TRUE, diff(index) > 1)))))
out[order(out$index),]
#          index  group id
# apple.1      1  apple  1
# apple.2      2  apple  1
# orange.3     3 orange  1
# orange.4     4 orange  1
# orange.5     5 orange  1
# orange.6     6 orange  1
# apple.7      7  apple  2
# apple.8      8  apple  2
# orange.9     9 orange  2
# apple.10    10  apple  3

使用rownames(out) <- NULL可以輕松刪除名稱。 order部分不是必需的,但我希望以與其他解決方案相同的順序呈現它,而do.call / by不保留原始訂單。

使用data.table::rleid兩次的另一個選項:

dt[, gid := rleid(group)][, id := rleid(gid), .(group)]

我們也可以使用base R rle

with(dt, with(rle(group), rep(ave(seq_along(values),
            values, FUN = seq_along), lengths)))
#[1] 1 1 1 1 1 1 2 2 2 3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM