简体   繁体   中英

Add column to data frame based on values of another column in another row

I was searching for an answer to my specific problem, but I didn't find a conclusion. I found this: Add column to Data Frame based on values of other columns , but it was'nt exactly what I need in my specific case. I'm really a beginner in R, so I hope maybe someone can help me or has a good hint for me.

Here an example of what my data frame looks like:

ID     answer  1.partnerID  
125    3       715        
235    4       845         
370    7       985          
560    1       950          
715    5       235          
950    5       560          
845    6       370          
985    6       125          

I try to describe what I want to do on an example: In the first row is the data of the person with the ID 125. The first partner of this person is the person with ID 715. I want to create a new column, with the value of the answer of each person´s partner in it. It should look like this:

ID     answer  1.partnerID  1.partneranswer    
125    3       715          5
235    4       845          6
370    7       985          6
560    1       950          5
715    5       235          4
950    5       560          1
845    6       370          7
985    6       125          3

So R should take the value of the column 1.partnerID, which is in this case "715" and search for the row, where "715" is the value in the column ID (there are no IDs more than once). From this specific row R should take the value from the column answer (in this example that´s the "5") and put it into the new column "1.partneranswer", but in the row from person 125. I hope someone can understand what I want to do ...

My problem is that I can imagine how to write this for each row per hand, but I think there need to be an easiear way to do it for all rows in once? (especially because in my original data.frame are 5 partners per person and there are more than one column from which the values should be transfered, so it would come to many hours work to write it for each single row per hand).

I hope someone can help. Thank you!

One solution is to use apply as follows:

df$partneranswer <- apply(df, 1, function(x) df$answer[df$ID == x[3]])

Output will be as desired above. There may be a loop-less approach.

EDIT: Adding a loop-less (vectorized answer) using match :

df$partneranswer <- df$answer[match(df$X1.partnerID, df$ID)]
df
   ID answer X1.partnerID partneranswer
1 125      3          715             5
2 235      4          845             6
3 370      7          985             6
4 560      1          950             5
5 715      5          235             4
6 950      5          560             1
7 845      6          370             7
8 985      6          125             3

Update : This can be done with self join; The first two columns define a map relationship from ID to answer, in order to find the answers for the partner IDs, you can merge the data frame with itself with first data frame keyed on partnerID and the second data frame keyed on ID :

Suppose df is (fixed the column names a little bit):

df
#   ID answer partnerID
#1 125      3       715
#2 235      4       845
#3 370      7       985
#4 560      1       950
#5 715      5       235
#6 950      5       560
#7 845      6       370
#8 985      6       125


merge(df, df[c('ID', 'answer')], by.x = "partnerID", by.y = "ID")

#  partnerID  ID answer.x answer.y
#1       125 985        6        3
#2       235 715        5        4
#3       370 845        6        7
#4       560 950        5        1
#5       715 125        3        5
#6       845 235        4        6
#7       950 560        1        5
#8       985 370        7        6

Old answer : If the ID and partnerID are mapped to each other one on one, you can try:

df$partneranswer <- with(df, answer[sapply(X1.partnerID, function(partnerID) which(ID == partnerID))])

df
#   ID answer X1.partnerID partneranswer
#1 125      3          715             5
#2 235      4          845             6
#3 370      7          985             6
#4 560      1          950             5
#5 715      5          235             4
#6 950      5          560             1
#7 845      6          370             7
#8 985      6          125             3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM