【问题标题】:Replicate a row as many times to a dataframe when one specific value in the row is matched当行中的一个特定值匹配时,将一行复制到数据帧多次
【发布时间】:2017-08-24 10:59:31
【问题描述】:

我有一个看起来像的数据框

Age    Sex    Height    Weight   Status    obesity  
17      m      5.6      36.3     single    Normal  
30      f      4.5      80.5     married   Abnormal
31      f      5.5      60.7     single    Normal
35      m      4.9      110.9    single    Very Abnormal

我想要类似的东西

Age    Sex    Height    Weight   Status    obesity  
17      m      5.6      36.3     single    Normal  
30      f      4.5      80.5     married   Abnormal
31      f      5.5      60.7     single    Normal
35      m      4.9      110.9    single    Very Abnormal
30      f      4.5      80.5     married   Abnormal
30      f      4.5      80.5     married   Abnormal
30      f      4.5      80.5     married   Abnormal
30      f      4.5      80.5     married   Abnormal
30      f      4.5      80.5     married   Abnormal
35      m      4.9      110.9    single    Very Abnormal
35      m      4.9      110.9    single    Very Abnormal
35      m      4.9      110.9    single    Very Abnormal
35      m      4.9      110.9    single    Very Abnormal
35      m      4.9      110.9    single    Very Abnormal
35      m      4.9      110.9    single    Very Abnormal

要复制数据框中的一行,必须在特定列或所示行的值之一中满足特定条件,例如obesity == Abnormal。然后行的值需要被复制给定的次数。复制可以尽可能多,例如1000。

【问题讨论】:

  • 你可以使用df1[rep(seq_len(nrow(df1)), df1$specificcolumn),]
  • 谢谢。但是如果复制是基于条件说肥胖==异常呢。然后将其复制 1000 次。

标签: r dataframe replication


【解决方案1】:

这是一个通用的解决方案,可能有点过头了。这个想法是建立一个带有条件或规则的表来识别行和重复次数:

library(data.table)
rows_to_repeat <- tibble::tribble(
  ~rule,    ~n_rep,
  "obesity == 'Abnormal'",      5,
  "obesity == 'Very Abnormal'", 6,
  "Age > 30",                   2
  )
setDT(rows_to_repeat)[]
                         rule n_rep
1:      obesity == 'Abnormal'     5
2: obesity == 'Very Abnormal'     6
3:                   Age > 30     2

然后,我们遍历规则,选择满足规则的行并根据要求复制它们。最后将额外的行追加到原始数据集DT

rbindlist(
  c(list(DT), 
    unlist(
      lapply(seq_len(nrow(rows_to_repeat)), function(.i) 
        replicate(rows_to_repeat[.i, n_rep], 
                  DT[eval(parse(text = rows_to_repeat[.i, rule]))], 
                  simplify = FALSE)),
      recursive = FALSE)))
    Age Sex Height Weight  Status       obesity
 1:  17   m    5.6   36.3  single        Normal
 2:  30   f    4.5   80.5 married      Abnormal
 3:  31   f    5.5   60.7  single        Normal
 4:  35   m    4.9  110.9  single Very Abnormal
 5:  30   f    4.5   80.5 married      Abnormal
 6:  30   f    4.5   80.5 married      Abnormal
 7:  30   f    4.5   80.5 married      Abnormal
 8:  30   f    4.5   80.5 married      Abnormal
 9:  30   f    4.5   80.5 married      Abnormal
10:  35   m    4.9  110.9  single Very Abnormal
11:  35   m    4.9  110.9  single Very Abnormal
12:  35   m    4.9  110.9  single Very Abnormal
13:  35   m    4.9  110.9  single Very Abnormal
14:  35   m    4.9  110.9  single Very Abnormal
15:  35   m    4.9  110.9  single Very Abnormal
16:  31   f    5.5   60.7  single        Normal
17:  35   m    4.9  110.9  single Very Abnormal
18:  31   f    5.5   60.7  single        Normal
19:  35   m    4.9  110.9  single Very Abnormal

数据

library(data.table)
DT <- readr::read_table(
  "Age    Sex    Height    Weight   Status    obesity  
  17      m      5.6      36.3     single    Normal  
  30      f      4.5      80.5     married   Abnormal
  31      f      5.5      60.7     single    Normal
  35      m      4.9      110.9    single    Very Abnormal"
)
setDT(DT)

【讨论】:

    【解决方案2】:

    你可以这样做:

     df %>%
       filter(grepl('Abnormal',obesity)) %>%
       slice(rep(1:n(), each=5)) %>%
       rbind(df)
    

    给出(每行重复 5 次):

       Age Sex Height  Status       obesity
    1   30   f   80.5 married      Abnormal
    2   30   f   80.5 married      Abnormal
    3   30   f   80.5 married      Abnormal
    4   30   f   80.5 married      Abnormal
    5   30   f   80.5 married      Abnormal
    6   35   m  110.9  single Very Abnormal
    7   35   m  110.9  single Very Abnormal
    8   35   m  110.9  single Very Abnormal
    9   35   m  110.9  single Very Abnormal
    10  35   m  110.9  single Very Abnormal
    11  17   m   36.3  single        Normal
    12  30   f   80.5 married      Abnormal
    13  31   f   60.7  single        Normal
    14  35   m  110.9  single Very Abnormal
    

    【讨论】:

    • @Aramis7。谢谢。但是使用View(df) 不会显示整个复制记录。
    • 您是否先将输出保存到df?尝试用%&lt;&gt;% 替换%&gt;% 可能吗?
    猜你喜欢
    • 2021-03-29
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 2018-08-16
    • 2021-04-03
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    相关资源
    最近更新 更多