Подсчитайте, сколько раз группа значений появлялась в целом наборе данных - PullRequest
0 голосов
/ 06 февраля 2019

Мне нужно выяснить, сколько раз группа появлялась во всем наборе данных, и нумеровать ее рядом.ниже приведен пример данных.скажем, если Group1 появляется впервые, то нумеруйте его как 1 вдоль стороны, аналогично, если он снова появляется вниз по дорожке, нумеруйте его как 2 вдоль стороны и так далее ... для каждой группы .. пожалуйста, обратитесь к образцу данных и ожидаемому результатудля большей ясности.

Пример данных:

  Group
Group1
Group1
Group1
Group1
Group1
Group1
Group2
Group2
Group2
Group2
Group2
Group2
Group2
Group2
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group2
Group2
Group2
Group2
Group2
Group2
Group2
Group2
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group1
Group3
Group3
Group3
Group3
Group3
Group3
Group3
Group3
Group3
Group3

Ожидаемый результат:

   Group    No of times
Group1  1
Group1  1
Group1  1
Group1  1
Group1  1
Group1  1
Group2  1
Group2  1
Group2  1
Group2  1
Group2  1
Group2  1
Group2  1
Group2  1
Group1  2
Group1  2
Group1  2
Group1  2
Group1  2
Group1  2
Group1  2
Group1  2
Group2  2
Group2  2
Group2  2
Group2  2
Group2  2
Group2  2
Group2  2
Group2  2
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group1  3
Group3  1
Group3  1
Group3  1
Group3  1
Group3  1
Group3  1
Group3  1
Group3  1
Group3  1
Group3  1

Ответы [ 3 ]

0 голосов
/ 06 февраля 2019

Ответ Ронака великолепен по сравнению с моим, но вот решение dplyr / tidyr, которое я придумала в любом случае.Идея такова:

  1. Пронумеруйте строки в их первоначальном порядке.
  2. Сортируйте таблицу по группам.Разрывы между кластерами групп будут отмечены внезапным скачком номера строки (4, 5, 6, 15, 16, 17 ...).
  3. Назначьте номер кластера первой записи в каждомкластера, а затем заполните все NA.
library(dplyr)
library(tidyr)

df_clustered <- 
    df %>% 
    mutate(rownum = row_number()) %>% 
    arrange(Group) %>% 
    mutate(mark = case_when((rownum - lag(rownum)) == 1 ~ NA, TRUE ~ TRUE)) %>% 
    group_by(Group, mark) %>% 
    mutate(cluster_number = ifelse(mark == TRUE, row_number(), NA)) %>% 
    ungroup() %>% 
    fill(cluster_number) %>% 
    arrange(rownum) %>% 
    select(-rownum, -mark)

head(df_clustered, 20)
#> # A tibble: 20 x 3
#>    Group  Value cluster_number
#>    <chr>  <dbl>          <int>
#>  1 Group1   1                1
#>  2 Group1   2                1
#>  3 Group1   1                1
#>  4 Group1   1.3              1
#>  5 Group1   1.2              1
#>  6 Group1   1                1
#>  7 Group2   7                1
#>  8 Group2   6                1
#>  9 Group2   2                1
#> 10 Group2   1                1
#> 11 Group2  25                1
#> 12 Group2  23                1
#> 13 Group2  24                1
#> 14 Group2  25                1
#> 15 Group1  24                2
#> 16 Group1  23                2
#> 17 Group1  26                2
#> 18 Group1  23                2
#> 19 Group1  17                2
#> 20 Group1  11                2
0 голосов
/ 06 февраля 2019

Вот чистое решение для data.table.Он основан на rle() и rep():

library(data.table)

DT <- data.table(stringsAsFactors=FALSE,
                 Group = c("Group1", "Group1", "Group1", "Group1", "Group1", "Group1",
                           "Group2", "Group2", "Group2", "Group2", "Group2", "Group2",
                           "Group2", "Group2", "Group1", "Group1", "Group1", "Group1",
                           "Group1", "Group1", "Group1", "Group1", "Group2", "Group2", 
                           "Group2", "Group2", "Group2", "Group2", "Group2", "Group2", 
                           "Group1", "Group1", "Group1", "Group1", "Group1", "Group1"),
                 Value = c(1, 2, 1, 1.3, 1.2, 1, 7, 6, 2, 1, 25, 23, 24, 25, 24, 23, 26, 23,
                           17, 11, 2, 1, 1, 2, 2.3, 1, 3, 4, 1, 1, 2, 25, 26, 11, 17, 16)
)

lengthEncoding <- rle(DT$Group)
setDT(lengthEncoding)[, group_count := seq_len(.N), by="values"]
DT[, "No of times" := rep(lengthEncoding$group_count, lengthEncoding$lengths)]

print(DT)

Кстати, это решение быстрее принятого ответа:

Редактировать: Added @ chinsoon12'sкрасивый однострочник который заслуживает короны!

library(microbenchmark)
library(data.table)
library(dplyr)

df <- data.frame(stringsAsFactors=FALSE,
                 Group = c("Group1", "Group1", "Group1", "Group1", "Group1", "Group1",
                           "Group2", "Group2", "Group2", "Group2", "Group2", "Group2",
                           "Group2", "Group2", "Group1", "Group1", "Group1", "Group1",
                           "Group1", "Group1", "Group1", "Group1", "Group2", "Group2", 
                           "Group2", "Group2", "Group2", "Group2", "Group2", "Group2", 
                           "Group1", "Group1", "Group1", "Group1", "Group1", "Group1"),
                 Value = c(1, 2, 1, 1.3, 1.2, 1, 7, 6, 2, 1, 25, 23, 24, 25, 24, 23, 26, 23,
                           17, 11, 2, 1, 1, 2, 2.3, 1, 3, 4, 1, 1, 2, 25, 26, 11, 17, 16)
)

DT <- data.table(df)

results <- microbenchmark(
  RonakShah = {
    df %>% 
      mutate(new = rleid(Group)) %>%
      group_by(Group) %>%
      mutate(no_of_times = cumsum(c(1,diff(new) != 0))) %>%
      select(-new)
  },
  ismirsehregal = {
    lengthEncoding <- rle(DT$Group)
    setDT(lengthEncoding)[, group_count := seq_len(.N), by="values"]
    DT[, "No of times" := rep(lengthEncoding$group_count, lengthEncoding$lengths)]
  },
  chinsoon12 = {DT[, numtimes := 1L + c(0L, cumsum(diff(.I) > 1L)), by=.(Group)]}
)

print(results)
plot(results)

          expr      min       lq     mean   median       uq      max neval cld
     RonakShah 3.980914 4.253103 4.898788 4.500009 5.063746 8.021481   100   c
 ismirsehregal 1.494078 1.653283 1.937947 1.828487 2.023246 5.678442   100  b 
    chinsoon12 1.050436 1.239666 1.469426 1.440154 1.646369 2.572168   100 a  
0 голосов
/ 06 февраля 2019

В одну сторону, используя data.table rleid, мы создаем столбец new, который дает другое значение для каждого изменения в столбце Group.Затем мы group_by Group и для каждого изменения значения new мы увеличиваем счет с помощью cumsum.

library(data.table)
library(dplyr)

df %>% 
  mutate(new = rleid(Group)) %>%
  group_by(Group) %>%
  mutate(no_of_times = cumsum(c(1,diff(new) != 0))) %>%
  select(-new)


#   Group no_of_times
#1  Group1           1
#2  Group1           1
#3  Group1           1
#4  Group1           1
#5  Group1           1
#6  Group1           1
#7  Group2           1
#8  Group2           1
#9  Group2           1
#10 Group2           1
#11 Group2           1
#12 Group2           1
#13 Group2           1
#14 Group2           1
#15 Group1           2
#.....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...