Группы фильтров, которые имеют разницу больше, чем заданное значение c в R - PullRequest
0 голосов
/ 09 января 2020

Я на самом деле хочу сгруппировать по v1 и отфильтровать только те, у которых разница между min (v3) и max (v3) больше 6, у меня есть следующий кадр данных

v1  v2  v3
a   2   13
b   5   3
c   2   1
d   2   1
e   1   2
a   2   4
a   8   1
e   1   9
b   0   1
c   2   8
d   1   5

Если мы вычислим мы найдем:

a   “13-1”  =12
b   “3-1”   =2
c   “8-1”   =7
d   “5-1”   =4
e   “9-2”   =7

Таким образом, ожидаемый результат будет содержать значения групп a, c и e, поскольку они все> = 6

v1  v2  v3
a   2   13
c   2   1
e   1   2
a   2   4
a   8   1
e   1   9
c   2   8

Ответы [ 2 ]

2 голосов
/ 09 января 2020

Мы можем использовать dplyr для группировки по 'v1' и получить diff значение range для 'v3' меньше 6

library(dplyr)
df1 %>%
  group_by(v1)%>%
  filter(abs(diff(range(v3))) >= 6)
# A tibble: 7 x 3
# Groups:   v1 [3]
#  v1       v2    v3
#  <chr> <int> <int>
#1 a         2    13
#2 c         2     1
#3 e         1     2
#4 a         2     4
#5 a         8     1
#6 e         1     9
#7 c         2     8

Или мы можем arrange столбец 'v3', а затем filter на разницу значений first и last

df1 %>% 
    arrange(v1, v3) %>% 
    group_by(v1) %>% 
    filter(last(v3)  - first(v3) >=6)

Или с data.table

library(data.table)
setDT(df1)[, .SD[abs(diff(range(v3))) >= 6], by = v1]

Или с другим опция .I

setDT(df1)[df1[, .I[abs(diff(range(v3))) >= 6], by = v1]$V1]

или другая опция ave из base R

i1 <- with(df1, ave(v3, v1, FUN = function(x) abs(diff(range(x)))) >= 6)
df1[i1,]

или использование subset и tapply

subset(df1, v1 %in% names(which(tapply(v3, v1, 
           function(x) diff(range(x))) >=6)))

данные

df1 <- structure(list(v1 = c("a", "b", "c", "d", "e", "a", "a", "e", 
"b", "c", "d"), v2 = c(2L, 5L, 2L, 2L, 1L, 2L, 8L, 1L, 0L, 2L, 
1L), v3 = c(13L, 3L, 1L, 1L, 2L, 4L, 1L, 9L, 1L, 8L, 5L)), 
class = "data.frame", row.names = c(NA, 
-11L))
2 голосов
/ 09 января 2020

Мы можем group_by v1 и использовать diff на range из v3 значений.

library(dplyr)
df %>%  group_by(v1) %>% filter(diff(range(v3)) >= 6)

#  v1       v2    v3
#  <fct> <int> <int>
#1 a         2    13
#2 c         2     1
#3 e         1     2
#4 a         2     4
#5 a         8     1
#6 e         1     9
#7 c         2     8

ИЛИ мы также можем использовать max - min

df %>%  group_by(v1) %>%  filter(max(v3) - min(v3) >= 6)

Мы можем использовать то же самое в базе R ave

subset(df, ave(v3, v1, FUN = function(x) diff(range(x))) >= 6)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...