I would like to allocate topics starting from their lowest popularity to highest. My data looks like this:
library(tidyverse)
data <- data.frame(topic = c("A", "B", "C", "D", "E"),
id1 = c(1,2,3,1,2),
id2 = c(3,3,2,1,3),
id3 = c(1,1,3,3,2),
id4 = c(3,1,2,2,1),
id5 = c(2,2,1,3,1),
id6 = c(3,1,1,1,3)) %>%
mutate(popularity = rowSums(. == 3),) %>%
arrange(popularity)
topic id1 id2 id3 id4 id5 id6 popularity
1 B 2 3 1 1 2 1 1
2 C 3 2 3 2 1 1 2
3 D 1 1 3 2 3 1 2
4 E 2 3 2 1 1 3 2
5 A 1 3 1 3 2 3 3
With help of SO I am able to allocate the topic in each row to the first maximum value in that row. So what we did here is move the topic title from each row to the first occurence of value 3 (which is maximum is this case).
# create empty matrox of size of the data
my_matrix <- matrix(NA, nrow(data), ncol(data)-1)
# fill matrix with topic at first occurence of maximum value per row
my_matrix[cbind(seq_len(nrow(my_matrix)), max.col(data[,-1], 'first'))] <- data$topic
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] NA "B" NA NA NA NA
[2,] "C" NA NA NA NA NA
[3,] NA NA "D" NA NA NA
[4,] NA "E" NA NA NA NA
[5,] NA "A" NA NA NA NA
That's almost perfect despite the fact that multiple topics have been assigned to one id (person). I am looking for a loop or a sopihsticated ifelse that does the max.col(data[,-1], 'first')) <- data$topic substitution and remembers that column 2 (id2) is already served. The expected outcome should be:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] NA "B" NA NA NA NA
[2,] "C" NA NA NA NA NA
[3,] NA NA "D" NA NA NA
[4,] NA NA NA NA NA "E"
[5,] NA NA NA NA "A" NA
In the end, every topic is allocated only once, to someone who had a maximum preference for this topic.