2017-02-19 3 views
-1

Мне нужно подсчитать количество строк, которые имеют рейтинги 4 или более 4 для каждого фильма (столбец). А затем разделите его на общее количество оценок. Как это может быть сделано ? Посмотрите на изображение ниже для краткой идеи.Как я могу подсчитать строку из разных столбцов с условием

Table

Конечный результат должен быть что-то вроде

0.7000000, 'The Shawshank Redemption' 
0.5333333, 'Star Wars IV - A New Hope' 
0.5000000, 'Gladiator' 
0.4444444, 'Blade Runner' 
0.4375000, 'The Silence of the Lambs' 
+0

Добро пожаловать в StackOverflow! Пожалуйста, прочитайте информацию о [как задать хороший вопрос] (http://stackoverflow.com/help/how-to-ask) и как дать [воспроизводимый пример] (http://stackoverflow.com/questions/ 5963269/как к Make-A-пра-р-воспроизводимая-пример/5963610). Это облегчит вам помощь другим людям. – Jaap

ответ

0
ratings<-data.frame(User=c("John","Maria","Anton","Roger","Martina","Ana","Sergi","Marc","Jim","Chris") 
        ,Star.Wars.IV...A.New.Hope=c(1,5,NA,NA,4,2,NA,4,5,4) 
        ,Star.Wars.VI...Return.of.the.Jedi=c(5,3,NA,3,3,4,NA,NA,1,2) 
        ,Forrest.Gump=c(2,NA,NA,NA,4,4,3,NA,NA,2) 
        ) 
ratings 
 User Star.Wars.IV...A.New.Hope Star.Wars.VI...Return.of.the.Jedi Forrest.Gump 
1  John       1         5   2 
2 Maria       5         3   NA 
3 Anton      NA        NA   NA 
4 Roger      NA         3   NA 
5 Martina       4         3   4 
6  Ana       2         4   4 
7 Sergi      NA        NA   3 
8  Marc       4        NA   NA 
9  Jim       5         1   NA 
10 Chris       4         2   2 

Если вы хотите включить NA с в общих рейтингах подсчитывать:

colSums(ratings[,-1]>=4,na.rm=T)/nrow(ratings) 
 Star.Wars.IV...A.New.Hope Star.Wars.VI...Return.of.the.Jedi      Forrest.Gump 
           0.5        0.2        0.2 

Если вы хотите исключить NA сек от общего числа оценок подсчитывать:

colMeans(ratings[,-1]>=4,na.rm=T) 
 Star.Wars.IV...A.New.Hope Star.Wars.VI...Return.of.the.Jedi      Forrest.Gump 
        0.7142857143      0.2857142857      0.4000000000 
0

Вы можете использовать colMeans для расчета процента и stack результат в длинном формате:

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

df = data.frame(user = c("A", "B", "C", "D"), 
       movieA = c(4,2,NA,5), 
       movieB = c(1,1,NA,4)) 

stack(colMeans(df[-1] >= 4, na.rm = T)) 

#  values ind 
#1 0.6666667 movieA 
#2 0.3333333 movieB 

Чтобы увидеть, как это работает:

df[-1] >= 4      # returns a boolean matrix where ratings >= 4 gives TRUE 

#  movieA movieB 
#[1,] TRUE FALSE 
#[2,] FALSE FALSE 
#[3,]  NA  NA 
#[4,] TRUE TRUE 

И среднее булева вектора процент трас (с NA удалены), поэтому вычислить среднее значение для всех столбцов с colMeans даст вам процент тебе нужно.

1

Данные не в обычном порядке. df - это ваш dataframe с некоторыми временными значениями.

library(dplyr) 
df <- data_frame(user = letters[1:10], 
      m1 = c(1,5,NA,NA,4,2,NA,4,5,4), 
      m2 = c(5,3,NA,3,3,4,NA,NA,1,2), 
      m3 = c(2,NA,NA,NA,4,4,3,NA,NA,NA)) 
df 
# A tibble: 10 × 4 
# user m1 m2 m3 
# <chr> <dbl> <dbl> <dbl> 
#1  a  1  5  2 
#2  b  5  3 NA 
#3  c NA NA NA 
#4  d NA  3 NA 
#5  e  4  3  4 
#6  f  2  4  4 
#7  g NA NA  3 
#8  h  4 NA NA 
#9  i  5  1 NA 
#10  j  4  2 NA 

Давайте преобразуем его в key:value пару т.е. movie:rating, в этом случае.

library(tidyr)  
df <- gather(df, movie, rating, -user) 
df 
# A tibble: 30 × 3 
# user movie rating 
# <chr> <chr> <dbl> 
#1  a m1  1 
#2  b m1  5 
#3  c m1  NA 
#4  d m1  NA 
#5  e m1  4 
#6  f m1  2 
#7  g m1  NA 
#8  h m1  4 
#9  i m1  5 
#10  j m1  4 
# ... with 20 more rows 

Теперь легко подвести итоги.

df %>% group_by(movie) %>% summarise(countp = mean(rating>=4, na.rm=T)) 
# A tibble: 3 × 2 
# movie countp 
# <chr> <dbl> 
#1 m1 0.7142857 
#2 m2 0.2857143 
#3 m3 0.5000000 
+0

Эй, ваше решение правильно! Спасибо за помощь. Но есть небольшая проблема. Когда я использую: Подведите итог (Hello = sum (рейтинг> = 4, na.rm = TRUE)/n()) n() дает счету 20, в котором общее число пользователей. Мне нужно разделить его по количеству оценок для этого конкретного фильма. Поскольку некоторые пользователи не оценили некоторые фильмы. – vr9211

+0

@ vr9211: см. Мое второе решение/Psidom: используйте 'mean (..., na.rm = T)' вместо 'sum (..., na.rm = T)/n()'.PS: Поскольку это ваш первый вопрос: не забудьте перечесть ответ, который вы приняли (или любой другой ответ, который вы считаете полезным). Добро пожаловать на сайт! – mschilli

+0

@ vr9211 'group_by (movie)' позаботится об этом. Вы можете создать новые cols для проверки 'summaryize (count = n())' –

Смежные вопросы