Daina
Daina

Reputation: 431

efficiently match values and average column where TRUE

Having trouble just matching values and taking an average of a column when those values match up efficiently in R. Essentially I have a chess table that I have pulled data out of and want to get the average for each player's pre-chess rating based on who they played against.

If I have a dataframe:

number <- c(1:10) #number assigned to each player
rating <- c(1000,1200,1210,980,1000,1001,1100,1300,1100,1250) #rating of the player
df <- data.frame(number= number, rating = rating)

p1_games <- c(1,2,3,4,5) # player 1 played against players 2,3,4,5

I want to essentially do is check to see if the values in p1_games match a number in the table, and when they match, average the values in the ratings column. I just want to return one value and so I've had trouble trying to make ifelse() work:

avg_rate <- ifelse(p1_games %in% df$number, sum(df$rating)/length(p1_games)) #not working

I would like to like to avoid looping if possible but if there's no other efficient way that's fine. Just can't figure out what's up here. Ideally I'd like to apply this logic over many p*_games vectors.

If p1_games in df$number, sum each corresponding rating and divide by the number or ratings. So the output for p1_games in this case would be 1078. I feel like this is really simple but can't quite make this work.

Upvotes: 0

Views: 67

Answers (2)

Chris Watson
Chris Watson

Reputation: 1367

An alternate answer using data.table, which may be of use with larger data sets (although since p1_games isn't a column, I'm not sure):

> setDT(df)
> df[number %in% p1_games, mean(rating)]
[1] 1078

Upvotes: 2

Se&#241;or O
Se&#241;or O

Reputation: 17432

%in% is great at this kind of thing

> mean(df[number %in% p1_games, "rating"])
[1] 1078

Upvotes: 3

Related Questions