Результат фильтрации на основе разных условий для разных столбцов

avatar
island1996
8 августа 2021 в 17:22
63
3
0

Я хочу найти человека с самым низким средним баллом при соблюдении следующих критериев:

  1. Всего более 2 отзывов
  2. Более 3 просмотренных объектов
Люди оценка элемент
Мэри 1.0 а
Мэри 2.0 а
Джек 1,5 b
Джек 3.0 а
Джек 4.1 b
Кейт 0,8 а

Я написал такой код

df %>%
  group_by(people) %>%
  mutate(na = n()) %>%
  filter(na > 2)

df %>%
  group_by(item) %>%
  mutate(nb = n()) %>%
  filter(nb > 60)

df %>%
group_by(people) %>%
mutate(meanscore = mean(score))

Я не знаю, как объединить/микшировать результат. Кроме того, я думаю, что не записал это.

Источник

Ответы (3)

avatar
TarJae
8 августа 2021 в 20:12
0

С этим поддельным набором данных df:

   People score item
1    Mary   1.0    a
2    Kate   4.0    c
3    Jack   1.5    b
4    Jack   3.0    a
5    Jack   4.1    b
6    Kate   0.8    b
7    Mary   1.0    c
8    Mary   1.0    b
9    Jack   1.5    c
10   Mary   3.0    d
11   Jack   4.1    b
12   Kate   0.8    a
df <- structure(list(People = c("Mary", "Kate", "Jack", "Jack", "Jack", 
"Kate", "Mary", "Mary", "Jack", "Mary", "Jack", "Kate"), score = c(1, 
4, 1.5, 3, 4.1, 0.8, 1, 1, 1.5, 3, 4.1, 0.8), item = c("a", "c", 
"b", "a", "b", "b", "c", "b", "c", "d", "b", "a")), class = "data.frame", row.names = c(NA, 
-12L))

вы можете сделать:

library(dplyr)
df %>% 
    group_by(People) %>% 
    summarise(avg_score = mean(score), 
              Total_Review = n(), 
              distinct_items = n_distinct(item)) %>% 
    filter(avg_score==min(avg_score) & 
               Total_Review > 2 & 
               distinct_items > 3)

вы получаете:

People avg_score Total_Review distinct_items
  <chr>      <dbl>        <int>          <int>
1 Mary         1.5            4              4

Предположения и объяснение:

  1. Total_Review это n() после group_by(People)
  2. элементы различны: поэтому a,b,a = 2 или a,b,a,a,b,c = 3

Если эти предположения верны: Мы можем применить summarise с функциями: mean, n и n_distinct то мы можем применить логику filter.

island1996
8 августа 2021 в 20:31
1

Спасибо вам большое за ваш ответ! Это так ясно и понятно

avatar
Ray
8 августа 2021 в 18:06
0

Мне не совсем понятно, что вы хотите сделать, но, учитывая ваш код и вопрос о том, как выполнить слияние, следующее может помочь вам в работе.

# test data frame
df <- tibble::tribble(
  ~People, ~score, ~item,
   "Mary",      1,   "a",
   "Mary",      2,   "a",
   "Jack",    1.5,   "b",
   "Jack",      3,   "a",
   "Jack",    4.1,   "b",
   "Kate",    0.8,   "a"
  )

# counting occurrence
> df %>%
     group_by(item) %>%
     mutate(nb = n())
# A tibble: 6 x 4
# Groups:   item [2]
  People score item     nb
  <chr>  <dbl> <chr> <int>
1 Mary     1   a         4
2 Mary     2   a         4
3 Jack     1.5 b         2
4 Jack     3   a         4
5 Jack     4.1 b         2
6 Kate     0.8 a         4

Обратите внимание, что это приводит к "сгруппированному" кадру данных. Вы можете ungroup().

Вы также можете использовать встроенный count():

item_count <- df %>% count(item)
item_count
# A tibble: 2 x 2
  item      n
  <chr> <int>
1 a         4
2 b         2 

Используя {tidyverse}, вы объединяете кадры данных с xxx_joint(). Здесь мы используем left_join():

df <- df %>% left_join(item_count, by = "item")
df
# A tibble: 6 x 4
  People score item      n
  <chr>  <dbl> <chr> <int>
1 Mary     1   a         4
2 Mary     2   a         4
3 Jack     1.5 b         2
4 Jack     3   a         4
5 Jack     4.1 b         2
6 Kate     0.8 a         4

Теперь вы можете применить фильтрацию на основе группировки people.

df %>% group_by(People) %>% summarise(reviews = n(), mean_score = mean(score))
# A tibble: 3 x 3
  People reviews mean_score
  <chr>    <int>      <dbl>
1 Jack         3       2.87
2 Kate         1       0.8 
3 Mary         2       1.5 

df %>% group_by(People) %>% summarise(reviews = n(), mean_score = mean(score)) %>% filter(reviews >= 2)
# A tibble: 2 x 3
  People reviews mean_score
  <chr>    <int>      <dbl>
1 Jack         3       2.87
2 Mary         2       1.5

Примечание: обычно вы используете summarise() для агрегирования строки по отдельным группам. Сравните это с исходным использованием group_by() и mutate().

island1996
8 августа 2021 в 18:32
0

Спасибо за помощь!!! На самом деле, этот вопрос имеет 3 условия: 1. оцените самый низкий средний балл; 2 сделали более 2 обзоров; 3 сделал более 3 просмотренных предметов. Затем мне нужно найти человека, который отвечает ВСЕМ этим трем требованиям.

Ray
8 августа 2021 в 18:39
0

Вы найдете здесь много друзей, если предоставите воспроизводимый пример, отвечающий вашей проблеме. Подумайте о том, как вы строите свой фрейм данных, включающий критерии. Для начала разработайте свою первоначальную идею создания отдельных фреймов данных, отвечающих различным условиям. Затем объедините их с join и отфильтруйте имеющиеся у вас сокращения.

island1996
8 августа 2021 в 18:40
0

Большое спасибо, Рэй, и желаю тебе хорошего дня!!!!!!

avatar
forhad
8 августа 2021 в 17:58
0

Вы можете попробовать так:

people <- c('Mary', 'Mary', rep('Jack', 3), 'Kate')
score <- c(1, 2, 1.5, 3, 4.1, 0.8)
item <- c('a', 'a', 'b', 'a', 'b', 'a')

df <- cbind.data.frame(people, score, item)

df2 <- df %>% 
  group_by(people) %>% 
  filter(n() > 2, length(unique(item)) > 3) %>% 
  summarise(AVG_SCORE = mean(score)) %>% 
  ungroup() %>% 
  filter(AVG_SCORE == min(AVG_SCORE))

## n() for number of rows i.e number of reviews
## length(unique(item)) for number of unique items. 
## Then ungroup
## Then filter for the lowest average score

df2
island1996
8 августа 2021 в 18:35
0

Спасибо за ваш ответ!!!! На самом деле, этот вопрос имеет 3 условия: 1. оцените самый низкий средний балл; 2 сделали более 2 обзоров; 3 сделал более 3 просмотренных предметов. Затем мне нужно найти человека, который отвечает ВСЕМ этим трем требованиям.

island1996
8 августа 2021 в 18:39
0

Кажется, ваш код работает !!!!!! Ценить!!! Хотя могу я спросить «длина (уникальный (элемент))> 3)», означает ли эта часть 【подсчитать количество по элементу, а затем отфильтровать количество> 3】? Спасибо!!!!

Ray
8 августа 2021 в 18:42
0

unique() дает вам «уникальные» отдельные элементы вектора, например. c(a, a, b, a, b, c) приведет к a, b, c. length() дает вам длину вектора, таким образом, length(a,b,c) = 3. С помощью ?function вы можете получить доступ к встроенной справке R, чтобы прочитать о различных функциях.