根据来自不同数据框的第二(较短)列的值将值分配给列

时间:2018-10-12 10:13:31

标签: r dataframe data-structures

我有两个不同长度的简单数据帧。 第一个数据框包含名称和相应的数字用户ID的列表。

names<-c("User1", "User2", "User3", "User4")
user_id<-c(1,2,3,4)
frame1<-as.data.frame(cbind(user_id, names))

user_id  names
1        User1
2        User2
3        User3
4        User4

第二个数据帧具有不同的长度,并包含带有注释的列和进行注释的人的相应user_id。用户可以发表多条评论,从而导致在colum frame2 $ comment_by

中具有相同user_id的多行
comment_by<-c(1,1,1,1,2,2,2,3,3,3,4,4)
comments<-c("comment1", "comment2","comment3","comment4","comment5","comment6","comment7","comment8","comment9","comment10","comment11","comment12")

frame2<-as.data.frame(cbind(comment_by, comments))

extracol<-c("full names")
frame2[,extracol]<-NA
frame2<-frame2[,c("comment_by", "full names", "comments")]

产生这样的数据帧

comment_by   full names   comments
1            NA           comment1
1            NA           comment2
1            NA           comment3
1            NA           comment4
2            NA           comment5
2            NA           comment6
2            NA           comment7
3            NA           comment8
3            NA           comment9
3            NA           comment10
4            NA           comment11
4            NA           comment12

如您所见,我已经在第二个数据框中添加了一个空的额外列(“全名”)。 我现在的目标是为每个注释将正确的名称从frame1分配给frame2 $“全名”列,因为frame2 $ comment_by列仅显示user_id,而不显示相应的名称。所以应该像这样:

comment_by   full names   comments
1            User1           comment1
1            User1           comment2
1            User1           comment3
1            User1           comment4
2            User2           comment5
2            User2           comment6
2            User2           comment7
3            User3           comment8
3            User3           comment9
3            User3           comment10
4            User4           comment11
4            User4           comment12

我尝试了一些简单的for循环/ if条件组合,但可以使其正常工作。

    x=1
    for (i in 1:length(frame2$comments)){
   if (is.na(frame2$comment_by[i])==is.na(frame1$user_id[x])) {
    frame2$`full names`[i]<-frame1$names[x]
    }else{x=x+1}
   i=i+1  }

我是否还需要for循环?我可以想象有一个简单的函数已经解决了这类问题。如果是这样,请告诉我。 (无论如何,为了学习,我也很高兴看到我的循环是否可以固定。)

1 个答案:

答案 0 :(得分:3)

欢迎使用StackeOverflow Rasul,并感谢您提供一个可复制的示例。

您无需添加额外的列即可执行所需的操作。您可以直接使用基本的merge()函数,该函数允许基于指定的列连接两个数据框:

names<-c("User1", "User2", "User3", "User4")
user_id<-c(1,2,3,4)
frame1<-as.data.frame(cbind(user_id, names))

comment_by<-c(1,1,1,1,2,2,2,3,3,3,4,4)
comments<-c("comment1", "comment2","comment3","comment4","comment5","comment6","comment7","comment8","comment9","comment10","comment11","comment12")

frame2<-as.data.frame(cbind(comment_by, comments))

# base R way
merge(frame2, frame1, by.x = "comment_by", by.y = "user_id")
#>    comment_by  comments names
#> 1           1  comment1 User1
#> 2           1  comment2 User1
#> 3           1  comment3 User1
#> 4           1  comment4 User1
#> 5           2  comment5 User2
#> 6           2  comment6 User2
#> 7           2  comment7 User2
#> 8           3  comment8 User3
#> 9           3  comment9 User3
#> 10          3 comment10 User3
#> 11          4 comment11 User4
#> 12          4 comment12 User4

# dplyr way
dplyr::inner_join(frame2, frame1, by = c("comment_by" = "user_id"))
#>    comment_by  comments names
#> 1           1  comment1 User1
#> 2           1  comment2 User1
#> 3           1  comment3 User1
#> 4           1  comment4 User1
#> 5           2  comment5 User2
#> 6           2  comment6 User2
#> 7           2  comment7 User2
#> 8           3  comment8 User3
#> 9           3  comment9 User3
#> 10          3 comment10 User3
#> 11          4 comment11 User4
#> 12          4 comment12 User4

reprex package(v0.2.1)于2018-10-12创建