根据特定列中的值重复数据框中的行

时间:2016-07-21 08:32:18

标签: r repeat

我想基于samples列重复数据框中的整行。

我的意见:

df <- 'chr start end samples
        1   10   20    2
        2   4    10    3'
df <- read.table(text=df, header=TRUE)

我的预期输出:

df <- 'chr start end  samples
        1   10   20   1-10-20-s1
        1   10   20   1-10-20-s2
        2   4    10   2-4-10-s1
        2   4    10   2-4-10-s2
        2   4    10   2-4-10-s3'

有些人明白如何明智地执行它?

3 个答案:

答案 0 :(得分:3)

您可以使用基本R(即避免data.tables)实现此目的,使用以下代码:

df <- 'chr start end samples
        1   10   20    2
        2   4    10    3'

df <- read.table(text = df, header = TRUE)

duplicate_rows <- function(chr, starts, ends, samples) {
  expanded_samples <- paste0(chr, "-", starts, "-", ends, "-", "s", 1:samples)
  repeated_rows <- data.frame("chr" = chr, "starts" = starts, "ends" = ends, "samples" = expanded_samples)

  repeated_rows
}

expanded_rows <- Map(f = duplicate_rows, df$chr, df$start, df$end, df$samples)

new_df <- do.call(rbind, expanded_rows)

基本思想是定义一个函数,该函数将根据samples列中的值从初始data.frame和重复行中获取一行(以及创建不同的字符串)后)。然后将此函数应用于初始data.frame的每一行。输出是data.frames的列表,然后需要使用do.call模式将其重新组合到单个data.frame中。

使用Hadley Wickham的purrr包(在CRAN上)以及map.frame特定版本的map(参见by_row函数的文档),可以使上面的代码更干净,但是对于你所追求的事情,这可能是过度的。

答案 1 :(得分:2)

我们可以使用expandRows根据'samples'列中的值展开行,然后转换为data.table,按'chr'分组,我们将列与序列一起粘贴在一起使用sprintf更新“示例”列的行。

library(splitstackshape)
setDT(expandRows(df, "samples"))[,
     samples := sprintf("%d-%d-%d-%s%d", chr, start, end, "s",1:.N) , chr][]
#  chr start end    samples
#1:   1    10  20 1-10-20-s1
#2:   1    10  20 1-10-20-s2
#3:   2     4  10  2-4-10-s1
#4:   2     4  10  2-4-10-s2
#5:   2     4  10  2-4-10-s3

注意:加载data.table时会加载splitstackshape

答案 2 :(得分:0)

使用S4Vector包中的DataFrame函数的示例:

df <- DataFrame(x=c('a', 'b', 'c', 'd', 'e'), y=1:5)
rep(df, df$y)

其中y列表示重复其相应行的次数。

结果:

DataFrame with 15 rows and 2 columns
              x         y
    <character> <integer>
1             a         1
2             b         2
3             b         2
4             c         3
5             c         3
...         ...       ...
11            e         5
12            e         5
13            e         5
14            e         5
15            e         5