在r中的同一数据集中连接行

时间:2018-02-28 05:52:32

标签: r dplyr left-join

我有一个如下所示的数据集:

       status    name.y  cost.y  name.x   cost.x
       foo       joe     1       steve    2
       bar       john    3       matt     4

并且我想对其进行转换,以使与状态相匹配的每一行与其对应的行连接在一起。所以看起来应该是这样的:

df %>% 
  left_join(
    x = ., y = ., by = 'status')
  )

我正在尝试使用这样的left_join:

  status cost.x name.x cost.y name.y
     foo      1    joe      1    joe
     foo      1    joe      2  steve
     foo      2  steve      1    joe
     foo      2  steve      2  steve
     bar      3   john      3   john
     bar      3   john      4   matt
     bar      4   matt      3   john
     bar      4   matt      4   matt

但我得到的结果是:

opendaylight-user@root>feature:install odl-ovsdb-southbound-impl-ui
opendaylight-user@root>

有什么想法吗?提前谢谢。

3 个答案:

答案 0 :(得分:0)

这是一个不优雅的黑客答案,但如果它像这样出现,你可以只过滤掉结果中每4行中第2行的所有内容。

答案 1 :(得分:0)

希望这有帮助!

library(dplyr)
library(splitstackshape) 

df %>%
  group_by(status) %>%
  summarise_all(funs(paste(.,collapse=","))) %>%
  cSplit(colnames(.)[-1],",")

输出是:

   status name_1 name_2 name_3 cost_1 cost_2 cost_3
1:    bar   john   matt     NA      3      4     NA
2:    foo    joe  steve   Prem      1      2      5

示例数据:

df <- structure(list(status = structure(c(2L, 2L, 1L, 1L, 2L), .Label = c("bar", 
"foo"), class = "factor"), name = structure(c(1L, 5L, 2L, 3L, 
4L), .Label = c("joe", "john", "matt", "Prem", "steve"), class = "factor"), 
    cost = c(1, 2, 3, 4, 5)), .Names = c("status", "name", "cost"
), row.names = c(NA, -5L), class = "data.frame")

答案 2 :(得分:0)

我们可以在tibble中的每一行放置2列,然后spreadunnest

library(tidyverse)
df$xy <- c("x","y")
df %>%
  transmute(status,name_cost=map2(name,cost,~tibble(name=.x,cost=.y)),xy) %>%
  spread(xy,name_cost) %>%
  unnest

#   status name cost name1 cost1
# 1    bar john    3  matt     4
# 2    foo  joe    1 steve     2

如果您使用df定义stringsAsFactors = FALSE,则可以使用此一个班轮,但请注意结果:

aggregate(cbind(name,cost) ~ status,df,identity)
#   status name.1 name.2 cost.1 cost.2
# 1    bar   john   matt      3      4
# 2    foo    joe  steve      1      2