代码之家  ›  专栏  ›  技术社区  ›  Cettt

将行绑定到每组tibble

  •  1
  • Cettt  · 技术社区  · 8 年前

    考虑以下两个问题 藏书 :

    library(tidyverse)
    a <- tibble(time = c(-1, 0), value = c(100, 200))
    b <- tibble(id = rep(letters[1:2], each = 3), time = rep(1:3, 2), value = 1:6)
    

    所以 a b 有相同的列和 有一个名为id的附加列。 我想做的是:小组 通过 id 然后添加tibble 在每个小组的最上面。 所以输出应该如下所示:

    # A tibble: 10 x 3
       id     time value
       <chr> <int> <int>
     1 a        -1     100
     2 a         0     200
     3 a         1     1
     4 a         2     2
     5 a         3     3
     6 b        -1     100
     7 b         0     200
     8 b         1     4
     9 b         2     5
    10 b         3     6
    

    当然,要实现这一点有多种解决方法(例如循环)。但在我的例子中,我有大量的id和大量的列。 如果有人能给我指一个解决办法的方向,我将不胜感激。

    谢谢你

    5 回复  |  直到 6 年前
        1
  •  3
  •   www    8 年前

    我们可以扩展数据框架 a 具有 id b 然后 bind_rows 他们在一起。

    library(tidyverse)
    
    a2 <- expand(a, id = b$id, nesting(time, value))
    b2 <- bind_rows(a2, b) %>% arrange(id, time)
    b2
    # # A tibble: 10 x 3
    #    id     time value
    #    <chr> <dbl> <dbl>
    #  1 a        -1   100
    #  2 a         0   200
    #  3 a         1     1
    #  4 a         2     2
    #  5 a         3     3
    #  6 b        -1   100
    #  7 b         0   200
    #  8 b         1     4
    #  9 b         2     5
    # 10 b         3     6
    
        2
  •  2
  •   Nathan Werth    8 年前

    split 从基r将数据帧划分为基于索引的子集列表。

    b %>%
      split(b[["id"]]) %>%
      lapply(bind_rows, a) %>%
      lapply(select, -"id") %>%
      bind_rows(.id = "id")
    # # A tibble: 10 x 3
    #    id     time value
    #    <chr> <dbl> <dbl>
    #  1 a         1     1
    #  2 a         2     2
    #  3 a         3     3
    #  4 a        -1   100
    #  5 a         0   200
    #  6 b         1     4
    #  7 b         2     5
    #  8 b         3     6
    #  9 b        -1   100
    # 10 b         0   200
    
        3
  •  1
  •   Sotos    8 年前

    一个想法(通过base r)是分割您的数据帧并创建一个id+另一个数据帧的新数据帧,然后 rbind ,即

    df = do.call(rbind, lapply(split(b, b$id), function(i)rbind(data.frame(id = i$id[1], a), i)))
    

    它给予

        id time value
    a.1  a   -1   100
    a.2  a    0   200
    a.3  a    1     1
    a.4  a    2     2
    a.5  a    3     3
    b.1  b   -1   100
    b.2  b    0   200
    b.3  b    1     4
    b.4  b    2     5
    b.5  b    3     6
    

    注: 只需调用 rownames(df) <- NULL

        4
  •  1
  •   moodymudskipper    8 年前

    我们可以将相关行嵌套并添加到每个嵌套项:

    library(tidyverse)
    
    b %>%
      nest(-id) %>%
      mutate(data= map(data,~bind_rows(a,.x))) %>%
      unnest
    
    # # A tibble: 10 x 3
    #       id  time value
    #    <chr> <dbl> <dbl>
    #  1     a    -1   100
    #  2     a     0   200
    #  3     a     1     1
    #  4     a     2     2
    #  5     a     3     3
    #  6     b    -1   100
    #  7     b     0   200
    #  8     b     1     4
    #  9     b     2     5
    # 10     b     3     6
    
        5
  •  0
  •   Danny    8 年前

    也许不是最有效的方法,但很容易做到:

    library(tidyverse)
    a <- tibble(time = c(-1, 0), value = c(100, 200))
    b <- tibble(id = rep(letters[1:2], each = 3), time = rep(1:3, 2), value = 
    1:6)
    
    a.a <- a %>% add_column(id = rep("a",length(a)))
    a.b <- a %>% add_column(id = rep("b",length(a)))
    joint <- bind_rows(b,a.a,a.b)
    (joint <- arrange(joint,id))