2017-02-19 56 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 /如何对化妆一个伟大-R-重复性,例如/ 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 S中的总收视率统计:

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 count:伯爵:

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 

和布尔向量的平均值TRUEs的比例(与NA删除),所以计算出的平均值与colMeans所有列会给你个你需要。

1

该数据不是一般整洁的格式。 df是具有某些临时值的数据帧。

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

嘿,你的解决方案是正确的!谢谢您的帮助。但是有一个小问题。 当我使用: 总结(你好=和(评级> = 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(电影)'会照顾到这一点。你可以创建新的cols来验证'summarize(count = n())' –