简体   繁体   中英

R How to apply function to several subsets

My dataset looks something like this:

movie.id unknown Action Adventure rating 
1        0       0      0         3.831461 
2        0       1      1         3.416667 
3        0       0      0         3.945946
4        0       1      0         2.894737
5        1       0      0         4.358491

I would like to compute mean rating of every genre. I can subset every one by hand, but I would like to do it more automatically

update1: every movie can have more than one genre, for every genre there is column with value 1 if movie is in the genre or 0 if is not

update2: so I would like to compute mean of ratings for every movie that have 1 in adventure column, and next for every movie that have 1 in action column, and unknown column (unknown is also genre) and so on

I believe this looks valid, too:

genres = names(DF)[2:4]
ret = lapply(genres, function(x) mean(DF[["rating"]][as.logical(DF[[x]])]))
cbind.data.frame(genres, means = unlist(ret)) #or whatever formating manipulation
#     genres    means
#1   unknown 4.358491
#2    Action 3.155702
#3 Adventure 3.416667

Where DF :

DF = structure(list(movie.id = 1:5, unknown = c(0L, 0L, 0L, 0L, 1L
), Action = c(0L, 1L, 0L, 1L, 0L), Adventure = c(0L, 1L, 0L, 
0L, 0L), rating = c(3.831461, 3.416667, 3.945946, 2.894737, 4.358491
)), .Names = c("movie.id", "unknown", "Action", "Adventure", 
"rating"), class = "data.frame", row.names = c(NA, -5L))

Using reshape2 and dplyr packages:

First install them:

> install.packages("reshape2")
> install.packages("dplyr")
> require(reshape2)
> require(dplyr)

then:

> m
  id unknown Action Adventure     rating
1  1       0      0         0 0.51391395
2  2       0      1         1 0.02915435
3  3       0      0         0 0.88752693
4  4       0      1         0 0.57660751
5  5       1      0         0 0.59169393

then its a one-liner:

> melt(m,measure=c("Action","Adventure","unknown")) %.% filter(value==1) %.% group_by(variable) %.% summarize(meanRating = mean(rating))
Source: local data frame [3 x 2]

   variable meanRating
1    Action 0.30288093
2 Adventure 0.02915435
3   unknown 0.59169393

Just to check, the only non-trivial one is:

> mean(m$rating[m$Action==1])
[1] 0.3028809

Set the measure= parameter to the names of your genre columns when you have lots of genres.

Change the name of the variable to get something a bit nicer:

> melt(m,measure=c("Action","Adventure","unknown"),variable.name="genre") %.% filter(value==1) %.% group_by(genre) %.% summarize(meanRating = mean(rating))
Source: local data frame [3 x 2]

      genre meanRating
1    Action 0.30288093
2 Adventure 0.02915435
3   unknown 0.59169393

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM