Merry upcoming Christmas - for those of us who celebrate it! # I have data frame x. x <- data.frame(game = c(rep(1, 4), rep(2, 4)), set = rep(c(1,1,2,2), 2), player = rep(1:2, 4), char1 = c(1,0,0,0,0,0,0,1), char2 c(0,0,1,0,0,1,0,0), char3 = c(0,1,0,1,0,0,0,0), char4 = c(0,0,0,0,1,0,1,0)) x # There are several games (2 here). Each game has several sets (2 here. In each set participate # several players (2 here). # Each player possesses 1 or 4 possible characteristics. # For example, in game 1, set 1, player 1 has characteristic 1 and player 2 - # characteristic 3 # I also have data frame myinfo: (myinfo <- data.frame(game = 1:2, set1 = c(3, 4), set2 = c(2, 1))) # It tells me: # in game 1, set 1 the winner was the player with characteristic 3 # in game 1, set 2 the winner was the player with characteristic 2, etc. # I need to merge the 2 to produce the result below. # I just need an additional column that - for each game and each set - # has a 1 in the row of the player who had the winning characteristic # (as per myinfo) and has a 0 otherwise. result <- x result$winner <- c(0, 1, 1, 0, 1, 0, 0, 1) result # I have written a long loop that loops through each set of each game, identifies # which characteristic wins in myinfo, and puts a 1 against the winning row. # But it's taking forever. Could it be done faster? Thanks a lot! # Important: In my real game the number of players could be more than 2 and so can # the number of games and the number of sets per game. # However, we can assume that the number of sets per game is always the same, # and the number of players per set is always the same. -- Dimitri Liakhovitski
Excellent job providing example data and a desired result. This code works on the example you provided. Hope it helps. Jean # reshape the info data frame library(tidyr) info2 <- gather(myinfo, set, val, -game) info2$set <- as.numeric(gsub("[[:alpha:]]", "", info2$set)) # add a new column to the x data frame y <- t(x[,grep("char", names(x))]) newx <- x newx$char <- row(y)[y==1] # merge and define winner res <- merge(newx, info2) res$winner <- with(res, ifelse(char==val, 1, 0)) res On Wed, Dec 23, 2015 at 3:35 PM, Dimitri Liakhovitski < dimitri.liakhovitski at gmail.com> wrote:> Merry upcoming Christmas - for those of us who celebrate it! > > # I have data frame x. > x <- data.frame(game = c(rep(1, 4), rep(2, 4)), set = rep(c(1,1,2,2), > 2), player = rep(1:2, 4), > char1 = c(1,0,0,0,0,0,0,1), char2 > c(0,0,1,0,0,1,0,0), char3 = c(0,1,0,1,0,0,0,0), > char4 = c(0,0,0,0,1,0,1,0)) > x > # There are several games (2 here). Each game has several sets (2 > here. In each set participate > # several players (2 here). > # Each player possesses 1 or 4 possible characteristics. > # For example, in game 1, set 1, player 1 has characteristic 1 and player > 2 - > # characteristic 3 > > # I also have data frame myinfo: > (myinfo <- data.frame(game = 1:2, set1 = c(3, 4), set2 = c(2, 1))) > # It tells me: > # in game 1, set 1 the winner was the player with characteristic 3 > # in game 1, set 2 the winner was the player with characteristic 2, etc. > > # I need to merge the 2 to produce the result below. > # I just need an additional column that - for each game and each set - > # has a 1 in the row of the player who had the winning characteristic > # (as per myinfo) and has a 0 otherwise. > > result <- x > result$winner <- c(0, 1, 1, 0, 1, 0, 0, 1) > result > > # I have written a long loop that loops through each set of each game, > identifies > # which characteristic wins in myinfo, and puts a 1 against the winning > row. > # But it's taking forever. Could it be done faster? Thanks a lot! > > # Important: In my real game the number of players could be more than > 2 and so can > # the number of games and the number of sets per game. > # However, we can assume that the number of sets per game is always the > same, > # and the number of players per set is always the same. > > > -- > Dimitri Liakhovitski > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
Jean and Dennis, thank you so much for your solutions! They are super-fast, thanks a lot! Happy new year! Dimitri On Thu, Dec 24, 2015 at 2:50 PM, Adams, Jean <jvadams at usgs.gov> wrote:> Excellent job providing example data and a desired result. > > This code works on the example you provided. Hope it helps. > > Jean > > # reshape the info data frame > library(tidyr) > info2 <- gather(myinfo, set, val, -game) > info2$set <- as.numeric(gsub("[[:alpha:]]", "", info2$set)) > > # add a new column to the x data frame > y <- t(x[,grep("char", names(x))]) > newx <- x > newx$char <- row(y)[y==1] > > # merge and define winner > res <- merge(newx, info2) > res$winner <- with(res, ifelse(char==val, 1, 0)) > res > > > On Wed, Dec 23, 2015 at 3:35 PM, Dimitri Liakhovitski > <dimitri.liakhovitski at gmail.com> wrote: >> >> Merry upcoming Christmas - for those of us who celebrate it! >> >> # I have data frame x. >> x <- data.frame(game = c(rep(1, 4), rep(2, 4)), set = rep(c(1,1,2,2), >> 2), player = rep(1:2, 4), >> char1 = c(1,0,0,0,0,0,0,1), char2 >> c(0,0,1,0,0,1,0,0), char3 = c(0,1,0,1,0,0,0,0), >> char4 = c(0,0,0,0,1,0,1,0)) >> x >> # There are several games (2 here). Each game has several sets (2 >> here. In each set participate >> # several players (2 here). >> # Each player possesses 1 or 4 possible characteristics. >> # For example, in game 1, set 1, player 1 has characteristic 1 and player >> 2 - >> # characteristic 3 >> >> # I also have data frame myinfo: >> (myinfo <- data.frame(game = 1:2, set1 = c(3, 4), set2 = c(2, 1))) >> # It tells me: >> # in game 1, set 1 the winner was the player with characteristic 3 >> # in game 1, set 2 the winner was the player with characteristic 2, etc. >> >> # I need to merge the 2 to produce the result below. >> # I just need an additional column that - for each game and each set - >> # has a 1 in the row of the player who had the winning characteristic >> # (as per myinfo) and has a 0 otherwise. >> >> result <- x >> result$winner <- c(0, 1, 1, 0, 1, 0, 0, 1) >> result >> >> # I have written a long loop that loops through each set of each game, >> identifies >> # which characteristic wins in myinfo, and puts a 1 against the winning >> row. >> # But it's taking forever. Could it be done faster? Thanks a lot! >> >> # Important: In my real game the number of players could be more than >> 2 and so can >> # the number of games and the number of sets per game. >> # However, we can assume that the number of sets per game is always the >> same, >> # and the number of players per set is always the same. >> >> >> -- >> Dimitri Liakhovitski >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide >> http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. > >-- Dimitri Liakhovitski