Удаление групп из фрейма данных, если переменная имеет повторяющиеся значения - PullRequest
0 голосов
/ 10 мая 2018

Я хотел бы спросить, существует ли способ удаления группы из фрейма данных с использованием dplyr (или другого способа в этом отношении) следующим образом.Допустим, у меня есть кадр данных в следующей форме, сгруппированный по переменной 1:

Variable 1   Variable 2
1            a
1            b     
2            a
2            a
2            b
3            a
3            c
3            a
...          ...

Я хотел бы удалить только те группы, которые имеют в переменной 2 два последовательных одинаковых значения.То есть в приведенной выше таблице будет удалена группа 2, потому что есть значения a, a, b, но нет группы c, где есть a, c, a.Так я бы получил таблицу ниже?

Variable 1   Variable 2
1            a
1            b     
3            a
3            c
3            a
...          ...

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Чтобы проверить последовательных идентичных значений, вы можете сравнить значение с предыдущим значением в этом столбце.В dplyr это возможно с lag.(Вы можете сделать то же самое, сравнив со следующим значением, используя lead. Результат будет таким же.)

Сгруппируйте данные по variable1, получите lag из variable2,затем сложите, сколько таких дубликатов в этой группе.Затем отфильтруйте только группы без дубликатов.После этого не стесняйтесь удалить столбец dupesInGroup.

library(tidyverse)

df %>%
    group_by(variable1) %>%
    mutate(dupesInGroup = sum(variable2 == lag(variable2), na.rm = T)) %>%
    filter(dupesInGroup == 0)
#> # A tibble: 5 x 3
#> # Groups:   variable1 [2]
#>   variable1 variable2 dupesInGroup
#>       <int> <chr>            <int>
#> 1         1 a                    0
#> 2         1 b                    0
#> 3         3 a                    0
#> 4         3 c                    0
#> 5         3 a                    0

Создан в 2018-05-10 пакетом Представить (v0.2.0).

0 голосов
/ 11 мая 2018

подготовить фрейм данных:

df <- data.frame("Variable 1" = c(1, 1, 2, 2, 2, 3, 3, 3), "Variable 2" = unlist(strsplit("abaabaca", "")))

написать функции для проверки наличия или отсутствия последовательных повторений:

any.consecutive.p <- function(v) {
  for (i in 1:(length(v) - 1)) {
    if (v[i] == v[i + 1]) {
      return(TRUE)
    }
  }
  return(FALSE)
}

any.consecutive.in.col.p <- function(df, col) {
  any.consecutive.p(df[, col])
}

any.consecutive.p возвращает TRUE, если он находит первый последовательный повторв векторе (v).any.consecutive.in.col.p () ищет последовательные повторения в столбце фрейма данных.

разделить фрейм данных по значениям Variable.1

df.l <- split(df, df$Variable.1)

df.l
$`1`
  Variable.1 Variable.2
1          1          a
2          1          b

$`2`
  Variable.1 Variable.2
3          2          a
4          2          a
5          2          b

$`3`
  Variable.1 Variable.2
6          3          a
7          3          c
8          3          a

Наконец перейдитеэтот список data.frame и тест для каждого фрейма данных, если он содержит последовательные дубликаты в столбце Variable.2.Если найдено, не собирайте его.Свяжите собранные кадры данных по строкам.

Reduce(rbind, lapply(df.l, function(df) if(!any.consecutive.in.col.p(df, "Variable.2")) {df}))

  Variable.1 Variable.2
1          1          a
2          1          b
6          3          a
7          3          c
8          3          a
0 голосов
/ 10 мая 2018

Скажем, вы хотите удалить все группы df, сгруппированные по a, где столбец b имеет повторяющиеся значения. Вы можете сделать это, как показано ниже.

set.seed(0)
df <- data.frame(a = rep(1:3, rep(3, 3)), b = sample(1:5, 9, T))


# dplyr
library(dplyr)

df %>% 
  group_by(a) %>% 
  filter(all(b != lag(b), na.rm = T))


#data.table
library(data.table)
setDT(df)

df[, if(all(b != shift(b), na.rm = T)) .SD, by = a]

Тест показывает, data.table быстрее

#Results
# Unit: milliseconds
#         expr       min        lq     mean    median        uq      max neval
#  use_dplyr() 141.46819 165.03761 201.0975 179.48334 205.82301 539.5643   100
#     use_DT()  36.27936  50.23011  64.9218  53.87114  66.73943 345.2863   100

# Method
set.seed(0)
df <- data.table(a = rep(1:2000, rep(1e3, 2000)), b = sample(1:1e3, 2e6, T))

use_dplyr <- function(x){
df %>% 
  group_by(a) %>% 
  filter(all(b != lag(b), na.rm = T))
}


use_DT <- function(x){

  df[, if (all(b != shift(b), na.rm = T)) .SD, a]

}

microbenchmark(use_dplyr(), use_DT())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...