我想基于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'
有些人明白如何明智地执行它?
答案 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