【问题标题】:Appending each element in a vector of strings to a repeating sequence of numbers将字符串向量中的每个元素附加到重复的数字序列中
【发布时间】:2019-09-21 00:59:55
【问题描述】:

我有一个没有示例名称的数据框。我有这些样本名称的向量,但长度不等于数据框中的行。这是因为每个样本都有几个“峰值”行。

我想将样本名称向量的第一个元素附加到“Peaks”中从 1 开始的每个重复数字序列。

这是我所拥有的:

Sample_Names <- c("S1","S2","S3")

Data <- tibble(Peak = c(1:3,1:2,1:4),
                   Value = c(101:109))



Peak Value
 1    101       
 2    102       
 3    103       
 1    104       
 2    105       
 1    106       
 2    107       
 3    108       
 4    109

我想按顺序添加我的 sample_names 向量的每个元素,以得到每个重复的数字序列:

Sample Peak Value
S1     1    101     
S1     2    102     
S1     3    103     
S2     1    104     
S2     2    105     
S3     1    106     
S3     2    107     
S3     3    108     
S3     4    109 

任何帮助将不胜感激:)

【问题讨论】:

  • 其中几个解决方案效果很好,谢谢!将 Sample_Name 分配给序列中的每个第一个数字,然后进行填充非常简单。干杯!

标签: r dataframe data.table


【解决方案1】:

dplyr 的一个选项是 replicate 'Sample_Names' 在获得具有累积总和的分组元素的计数后

library(dplyr)
Data %>%
    mutate(Sample =  rep(Sample_Names, tabulate(cumsum(Peak==1))))
# A tibble: 9 x 3
#   Peak Value Sample
#  <int> <int> <chr> 
#1     1   101 S1    
#2     2   102 S1    
#3     3   103 S1    
#4     1   104 S2    
#5     2   105 S2    
#6     1   106 S3    
#7     2   107 S3    
#8     3   108 S3    
#9     4   109 S3   

或者使用data.table

library(data.table)
setDT(Data)[, Sample := rep(Sample_Names, tabulate(cumsum(Peak==1))) ]

或者另一个选项是na.locf from zoo

library(zoo)
setDT(Data)[Peak == 1, Sample := Sample_Names][, Sample := na.locf(Sample)][]

【讨论】:

    【解决方案2】:
    library(dplyr)
    library(tidyr)
    
    Data %>%
        group_by(Peak) %>%
        mutate(Sample = row_number()) %>%
        ungroup() %>%
        mutate(Sample = Sample_Names[cummax(Sample)])
    

    在 Base R 中,你可以这样做

    Sample_Names[cummax(ave(Data$Peak, Data$Peak, FUN = seq_along))]
    

    【讨论】:

    • 你可以使用 rowid from data.table` Data %&gt;% mutate(Sample = Sample_Names[cummax(rowid(Peak))])
    【解决方案3】:

    我们可以创建一个计数器,当Peak == 1 使用cumsum 时递增,并将其用于子集Sample_Names

    Data$Sample <- Sample_Names[cumsum(Data$Peak == 1)]
    
    # A tibble: 9 x 3
    #   Peak Value Sample
    #  <int> <int> <chr> 
    #1     1   101 S1    
    #2     2   102 S1    
    #3     3   103 S1    
    #4     1   104 S2    
    #5     2   105 S2    
    #6     1   106 S3    
    #7     2   107 S3    
    #8     3   108 S3    
    #9     4   109 S3    
    

    我们也可以使用tidyr::fill

    library(dplyr)
    Data %>%
      mutate(Sample = ifelse(Peak == 1, Sample_Names, NA)) %>%
      tidyr::fill(Sample)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-15
      • 1970-01-01
      • 2011-09-19
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      相关资源
      最近更新 更多