Search code examples
rvectorelementassign

Assigning elements of one vector to elements of another with R


I would like to assign elements of one vector to elements of another for every single user.

For example:

Within a data frame with the variables "user", "activities" and "minutes" (see below), I would like to assign, for example, the duration (4 minutes) of the first activity (4 minutes to activity "READ") of user 1 to new variable READ_duration. Then duration (5 minutes) of second activity ("EDIT") to the new variable EDIT_duration. And the duration (2 minutes) of third activity (again "READ") to the new variable READ_duration.

user <- 1,2,3

activities <- c("READ","EDIT","READ"), c("READ","EDIT", "WRITE"), c("WRITE","EDIT")

minutes <- c(4,5,2), c(3.5, 1, 2), c(4.5,3)

Output should be like: in a data frame with the assigned minutes to the activities:

user READ_duration EDIT_duration WRITE_duration

1        6               5                0
2        3.5             1                2
3        0               3                4.5    

The tricky thing here is the algorithm needs to consider that the activities are not in the same order for every user. For example, user 3 starts with writing and therefore the duration 4.5 needs to be assigned to column 4 WRITE_duration.

Also, a loop-function would be needed due to a massive amount of users.

Thank you so much for your help!!


Solution

  • This needs a simple reshape to wide format with sum as an aggregation function.

    Prepare a long-format data.frame:

    user <- c(1,2,3)
    
    activities <- list(c("READ","EDIT","READ"), c("READ","EDIT", "WRITE"), c("WRITE","EDIT"))
    
    minutes <- list(c(4,5,2), c(3.5, 1, 2), c(4.5,3))
    
    
    DF <- Map(data.frame, user = user, activities = activities, minutes = minutes)
    DF <- do.call(rbind, DF)
    #  user activities minutes
    #1    1       READ     4.0
    #2    1       EDIT     5.0
    #3    1       READ     2.0
    #4    2       READ     3.5
    #5    2       EDIT     1.0
    #6    2      WRITE     2.0
    #7    3      WRITE     4.5
    #8    3       EDIT     3.0
    

    Reshape:

    library(reshape2)
    dcast(DF, user ~ activities, value.var = "minutes", fun.aggregate = sum)
    #  user EDIT READ WRITE
    #1    1    5  6.0   0.0
    #2    2    1  3.5   2.0
    #3    3    3  0.0   4.5