【问题标题】:Expand data frame in R by duplicating and substituting variable using piping通过使用管道复制和替换变量来扩展 R 中的数据框
【发布时间】:2020-05-19 06:43:08
【问题描述】:

我想使用以下方式扩展数据框:

GX 将被三个不同的变量 Gs = (G4, G5, G6 替换,它们都将保留 GX 的属性值。对于每个新的Gs,当前的GX 行必须重复,GX 名称必须替换为相应的Gs 名称。

  set.seed(123)
  df = data.frame(
    "id" = c(rep("G1", 3), rep("G2", 3), rep("G3", 3), rep("GX",3)),
    "subgroup" = rep(c(1,2,3), 4),
    "total" = sample.int(n = 12),
    "C1" = sample.int(n=12),
    "C2" = sample.int(n=12),
    "C3" = sample.int(n=12))

   id subgroup total C1 C2 C3
1  G1        1     3 11  9  9
2  G1        2    12  5  3 12
3  G1        3    10  3  4 10
4  G2        1     2  9  1  7
5  G2        2     6  4 11  3
6  G2        3    11  1  7  4
7  G3        1     5  7  5  5
8  G3        2     4 12 10  6
9  G3        3     9 10  8  8
10 GX        1     8  2  2  2
11 GX        2     1  6 12  1
12 GX        3     7  8  6 11

我有一个解决方案,其中包含 for loop

  Gs = c("G4", "G5", "G6")
  for (ii in 1:length(Gs)) {
    tmp.df <- df[df$id == "GX",]
    tmp.df$id <- gsub(
      pattern = "GX", 
      replacement = Gs[ii],
      x = tmp.df$id
    )
    df <- rbind(df, tmp.df)
  }
  df = df[df$id != "GX",]

这给出了:

id subgroup total C1 C2 C3
1   G1        1     3 11  9  9
2   G1        2    12  5  3 12
3   G1        3    10  3  4 10
4   G2        1     2  9  1  7
5   G2        2     6  4 11  3
6   G2        3    11  1  7  4
7   G3        1     5  7  5  5
8   G3        2     4 12 10  6
9   G3        3     9 10  8  8
101 G4        1     8  2  2  2
111 G4        2     1  6 12  1
121 G4        3     7  8  6 11
102 G5        1     8  2  2  2
112 G5        2     1  6 12  1
122 G5        3     7  8  6 11
103 G6        1     8  2  2  2
113 G6        2     1  6 12  1
123 G6        3     7  8  6 11

但是我想将解决方案包含在管道中并避免使用for loop 解决方案。是否有更多使用 tidyverse 语法 包含在 pipe 中的 R 时尚方法?

谢谢

【问题讨论】:

    标签: r pipe tidyverse


    【解决方案1】:

    我们可以只选择id == 'GX' 所在的行,使用Gs 创建它的所有组合,并将原始数据框绑定到它,删除'Gx' 行。

    library(dplyr)
    
    df %>%
      filter(id == 'GX') %>%
      tidyr::crossing(Gs) %>%
      select(-id, id = Gs) %>%
      bind_rows(df, .) %>%
      filter(id != 'GX')
    
    
    #   id subgroup total C1 C2 C3
    #1  G1        1     3 11  9  9
    #2  G1        2    12  5  3 12
    #3  G1        3    10  3  4 10
    #4  G2        1     2  9  1  7
    #5  G2        2     6  4 11  3
    #6  G2        3    11  1  7  4
    #7  G3        1     5  7  5  5
    #8  G3        2     4 12 10  6
    #9  G3        3     9 10  8  8
    #10 G4        1     8  2  2  2
    #11 G5        1     8  2  2  2
    #12 G6        1     8  2  2  2
    #13 G4        2     1  6 12  1
    #14 G5        2     1  6 12  1
    #15 G6        2     1  6 12  1
    #16 G4        3     7  8  6 11
    #17 G5        3     7  8  6 11
    #18 G6        3     7  8  6 11
    

    【讨论】:

    • 谢谢。这将与添加最后一条管道后的结果完全匹配 dplyr::arrange(id, subgroup)
    【解决方案2】:

    Ronak Shah here 之前回答了这个问题。复制他在那里所做的:

    library(dplyr)
    library(tidyr)
    
    set.seed(123)
    df = data.frame(
      "id" = c(rep("G1", 3), rep("G2", 3), rep("G3", 3), rep("GX",3)),
      "subgroup" = rep(c(1,2,3), 4),
      "total" = sample.int(n = 12),
      "C1" = sample.int(n=12),
      "C2" = sample.int(n=12),
      "C3" = sample.int(n=12))
    
    
    df2 <- df %>%
      filter(id == "GX") %>%
      group_by(id) %>%
      slice(rep(seq_len(n()), n()))
    

    给你:

    > df2
    # A tibble: 9 x 6
    # Groups:   id [1]
      id    subgroup total    C1    C2    C3
      <fct>    <dbl> <int> <int> <int> <int>
    1 GX           1     8     2     2     2
    2 GX           2     1     6    12     1
    3 GX           3     7     8     6    11
    4 GX           1     8     2     2     2
    5 GX           2     1     6    12     1
    6 GX           3     7     8     6    11
    7 GX           1     8     2     2     2
    8 GX           2     1     6    12     1
    9 GX           3     7     8     6    11
    

    这与您所追求的非常接近。

    【讨论】:

      猜你喜欢
      • 2021-11-29
      • 2021-12-18
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 2018-07-18
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多