根据另一行的列值,在数据框中添加列

5
我在寻找一个解决我特定问题的答案,但是没有找到结论。我发现了这个网站:Add column to Data Frame based on values of other columns ,但它并不完全符合我特定情况下的需求。 我是R语言的初学者,希望有人能够帮助或给我一些提示。
这里是我的数据框示例:
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          

我将通过一个示例来描述我的意图: 第一行是ID为125的人的数据。这个人的第一个伙伴是ID为715的人。我想创建一个新列,其中包含每个人伙伴的答案值。它应该看起来像这样:

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

所以R应该获取列1.partnerID的值,这个例子中为"715",然后在ID列中搜索值为"715"的行(ID没有重复)。 从这一行开始,R应该获取answer列中的值(在这个例子中是"5"),并将其放入新的列"1.partneranswer"中,但是放在人员125的行中。 我希望有人能理解我想做什么... 我的问题是,我可以想象如何逐行手动编写此代码,但我认为需要一种更简便的方法来批量处理所有行? (特别是因为在我的原始数据框中,每个人都有5个合作伙伴,并且还有多个列需要转移值,因此为每个单独的行编写它需要花费很多时间)。 希望有人能帮忙。 谢谢!
2个回答

9
一种解决方案是使用以下方式的apply函数:
df$partneranswer <- apply(df, 1, function(x) df$answer[df$ID == x[3]])

输出将如上所述。可能有一种无需循环的方法。

编辑:使用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

1
哇,非常感谢您的快速回复! 它与 df$partneranswer <- df$answer[match(df$X1.partnerID, df$ID)] 一起工作了!我寻找解决方案已经很长时间了,没想到它可以如此简单和短!您帮了我很多忙! :-) - esia_1

1

更新:这可以通过自连接完成;前两列定义了从ID到答案的映射关系,为了找到合作伙伴ID的答案,您可以将第一个数据帧键入partnerID,将第二个数据帧键入ID,然后将它们合并:

假设df是(稍微固定了一下列名):

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

如果ID和partnerID是一对一映射的,你可以尝试以下方法:

旧答案

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

感谢您的快速回复!ID和partnerID没有映射在一起,我甚至不知道这是如何工作的。但是我在Gopala的帖子中找到了一个解决方案! - esia_1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接