umair durrani
umair durrani

Reputation: 6155

How to get a value of a column in a matrix based on the values in another matrix?

Data

I have 2 matrices. traf_id represents the ID of two traffic lights in two columns (if the traffic light is closest to the car then it is located in the first column). The second matrix, traf_state represents the state (1 = red and 2 = green) of the traffic light (again, the state of the closest light is put in the first column).

traf_id <- matrix(data = c(rep(12353,4), rep(12453,4),  rep(12453,4), rep(12353,4)), nrow = 8, ncol = 2)
      [,1]  [,2]
[1,] 12353 12453
[2,] 12353 12453
[3,] 12353 12453
[4,] 12353 12453
[5,] 12453 12353
[6,] 12453 12353
[7,] 12453 12353
[8,] 12453 12353  


traf_state <- matrix(data = c(rep(1,8), rep(2,8)), nrow = 8, ncol = 2)
     [,1] [,2]
[1,]    1    2
[2,]    1    2
[3,]    1    2
[4,]    1    2
[5,]    1    2
[6,]    1    2
[7,]    1    2
[8,]    1    2  

In the above data, traffic light 12353 is the closest to the car for the first 4 time frames (with traf_state equal to 1) and therefore, put in the first column. From frames 5 to 8, 12453 is the closest one.

What I want to do

I want to create a data frame with 3 columns. The first should be time frame column and the other two should contain the traffic state of a given traffic light for the given time frame:

foo <- data.frame(frames = 1:8, state_12353 = c(rep(1,4), rep(2,4)), state_12453 = c(rep(2,4), rep(1,4)))
> foo
  frames state_12353 state_12453
1      1           1           2
2      2           1           2
3      3           1           2
4      4           1           2
5      5           2           1
6      6           2           1
7      7           2           1
8      8           2           1 

Please guide me what functions in dplyr are relevant to create the above data frame.

Upvotes: 0

Views: 47

Answers (1)

akuiper
akuiper

Reputation: 214917

It seems you have row representing the time frames, and columns representing the relative positions of the traffic light to the car; To match the traffic light id with their state, you need to gather the original data to long format so the coordinates (time and positions) become two separate columns which you can then join on:

# make the data frames
traf_id_df <- data.frame(traf_id, frames = 1:8)
traf_state_df <- data.frame(traf_state, frames = 1:8)

library(dplyr); library(tidyr)
inner_join(
    gather(traf_id_df, Distance, Id, -frames), 
    gather(traf_state_df, Distance, State, -frames)
) %>% 
    select(-Distance) %>% 
    mutate(Id = paste0("state_", Id)) %>% 
    spread(Id, State)

#  frames state_12353 state_12453
#1      1           1           2
#2      2           1           2
#3      3           1           2
#4      4           1           2
#5      5           2           1
#6      6           2           1
#7      7           2           1
#8      8           2           1

Or since the elements in the two matrices correspond to each other, you can bind the two matrices element-wise, then reshape:

cbind(
    seq_len(nrow(traf_id)), 
    as.vector(traf_id), 
    as.vector(traf_state)
) %>% as.data.frame() %>% 
    setNames(c('frames', 'id', 'state')) %>% 
    mutate(id = paste0('state_', id)) %>% 
    spread(id, state)

#  frames state_12353 state_12453
#1      1           1           2
#2      2           1           2
#3      3           1           2
#4      4           1           2
#5      5           2           1
#6      6           2           1
#7      7           2           1
#8      8           2           1

Upvotes: 1

Related Questions