使用列名称向量将数据框的多个列(如对象)提取并粘贴在一起

时间:2016-11-24 15:05:02

标签: r packages bioinformatics

我有一个对象(变量rld)看起来有点像“data.frame”(详情请参见帖子的下方),因为它有可以使用$访问的列或[[]]

我有一个向量groups,其中包含一些列的名称(下例中为3)。

我根据列中元素的组合生成字符串,如下所示:

paste(rld[[groups[1]]], rld[[groups[2]]], rld[[groups[3]]], sep="-")

我想概括一下,以便我不需要知道groups中有多少元素。

以下尝试失败:

> paste(rld[[groups]], collapse="-")
Error in normalizeDoubleBracketSubscript(i, x, exact = exact, error.if.nomatch = FALSE) : 
  attempt to extract more than one element

以下是我在python词典中使用函数式的方法:

map("-".join, zip(*map(rld.get, groups)))

R中是否有类似的列-getter运算符

正如评论中所建议的,以下是dput(rld)的输出:http://paste.ubuntu.com/23528168/(我无法直接粘贴它,因为它很大。)

这是使用DESeq2生物信息学软件包生成的,更准确地说,是与本文档第28页所描述的内容类似:https://www.bioconductor.org/packages/release/bioc/vignettes/DESeq2/inst/doc/DESeq2.pdf

可以从bioconductor安装DESeq2,如下所示:

source("https://bioconductor.org/biocLite.R")
biocLite("DESeq2")

可重复的例子

其中一个solutions在交互模式下运行时有效,但在代码放入库函数时失败,出现以下错误:

Error in do.call(function(...) paste(..., sep = "-"), colData(rld)[groups]) : 
  second argument must be a list

经过一些测试后,如果函数在主调用脚本中,似乎不会出现问题,如下所示:

library(DESeq2)
library(test.package)

lib_names <- c(
    "WT_1",
    "mut_1",
    "WT_2",
    "mut_2",
    "WT_3",
    "mut_3"
)
file_names <- paste(
    lib_names,
    "txt",
    sep="."
)

wt <- "WT"
mut <- "mut"
genotypes <- rep(c(wt, mut), times=3)
replicates <- c(rep("1", times=2), rep("2", times=2), rep("3", times=2))

sample_table = data.frame(
    lib = lib_names,
    file_name = file_names,
    genotype = genotypes,
    replicate = replicates
)

dds_raw <- DESeqDataSetFromHTSeqCount(
    sampleTable = sample_table,
    directory = ".",
    design = ~ genotype
    )

# Remove genes with too few read counts
dds <- dds_raw[ rowSums(counts(dds_raw)) > 1, ]
dds$group <- factor(dds$genotype)
design(dds) <- ~ replicate + group
dds <- DESeq(dds)

test_do_paste <- function(dds) {
    require(DESeq2)
    groups <- head(colnames(colData(dds)), -2)
    rld <- rlog(dds, blind=F)
    stopifnot(all(groups %in% names(colData(rld))))
    combined_names <- do.call(
        function (...) paste(..., sep = "-"),
        colData(rld)[groups]
    )
    print(combined_names)
}

test_do_paste(dds)
# This fails (with the same function put in a package)
#test.package::test_do_paste(dds)

当函数打包为https://hilaryparker.com/2014/04/29/writing-an-r-package-from-scratch/

时,会发生错误

示例中使用的数据:

我将此问题作为单独的问题发布do.call error "second argument must be a list" with S4Vectors when the code is in a library

虽然我对最初的问题有了答案,但我仍然对“使用列名称向量列提取”问题的替代解决方案感兴趣。

1 个答案:

答案 0 :(得分:3)

我们可能会使用以下任何一项:

do.call(function (...) paste(..., sep = "-"), rld[groups])
do.call(paste, c(rld[groups], sep = "-"))

我们可以考虑一个小的,可重复的例子:

rld <- mtcars[1:5, ]
groups <- names(mtcars)[c(1,3,5,6,8)]
do.call(paste, c(rld[groups], sep = "-"))
#[1] "21-160-3.9-2.62-0"     "21-160-3.9-2.875-0"    "22.8-108-3.85-2.32-1" 
#[4] "21.4-258-3.08-3.215-1" "18.7-360-3.15-3.44-0"

请注意,您有责任确保all(groups %in% names(rld))TRUE,否则您的下标超出范围&#34;或&#34;选择未定义的列&#34;错误。

(我将您的评论复制为后续行动)

您建议的方法似乎不能直接在我的对象上工作。但是,我使用的软件包提供了一个colData函数,可以使data.frame更类似于:

> class(colData(rld))
[1] "DataFrame"
attr(,"package")
[1] "S4Vectors"

do.call(function (...) paste(..., sep = "-"), colData(rld)[groups])有效,但do.call(paste, c(colData(rld)[groups], sep = "-"))失败并显示错误消息我无法理解(通常使用R ...):

> do.call(paste, c(colData(rld)[groups], sep = "-"))
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘mcols’ for signature ‘"character"’