【问题标题】:Extract and paste together multiple columns of a data frame like object using a vector of column names使用列名向量提取并粘贴数据框的多列,如对象
【发布时间】:2016-11-25 22:35:56
【问题描述】:

我有一个对象(变量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 中是否有类似的 column-getter 运算符?


按照 cmets 中的建议,这里是 dput(rld) 的输出:http://paste.ubuntu.com/23528168/(我无法直接粘贴,因为它很大。)

这是使用 DESeq2 生物信息学包生成的,更准确地说,是在执行类似于本文档第 28 页所述的操作:https://www.bioconductor.org/packages/release/bioc/vignettes/DESeq2/inst/doc/DESeq2.pdf

DESeq2 可以从 bioconductor 安装如下:

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

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

【问题讨论】:

  • 您需要发布一个可重现的示例,如果您使用了dput(yourObject),那么我们就不必为 '我有一个看起来像有点像“data.frame”,因为它具有可以使用 $ 或 [[]]' 访问的列,真正的意思是:命名列表?数据表?还有什么?
  • 直到我看到可重现的数据阐明了 'object... 看起来有点像“data.frame”' 的含义,我才会投票结束。粘贴大约需要 60 秒。
  • @smci 我不知道dput。我使用 R 才几个月。我会试试这个。
  • @smci 我添加了一个可重现的例子
  • 好的,所以你的对象是DESeq2:: DESeqTransform。您可以只使用dput(head(dds), 10) 显示前几行,其他 750 不会添加太多。我不知道 DESeq2,但这里的其他人应该知道。并不是要胡思乱想,但是如果没有可重复的示例,我们将无能为力。抱歉,我无法撤回我的投票结束。顺便说一句,现在 R 中几乎所有新的数据结构都看起来像一个数据框 :) 很高兴看到您找到了解决方案。

标签: r packages bioinformatics


【解决方案1】:

我们可以使用以下任何一种:

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 是您的责任,否则您会收到“下标越界”或“未定义列已选择”错误。


(我复制你的评论作为后续)

您提出的方法似乎不适用于我的对象。但是,我正在使用的包提供了一个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"’

【讨论】:

  • 您提出的方法似乎不能直接作用于我的对象。但是,我使用的包提供了一个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 一样经常......)
  • 奇怪的是,当我在交互式会话中加载我的 R 脚本并手动使用 do.call 时,一切正常,但是当我使用命令行参数运行我的脚本时,它无法显示“do.call 中的错误” (function(...) paste(..., sep = "-"), colData(rld)[groups]) (from load_WT_prg1_data.R#80) : 第二个参数必须是一个列表”。
  • 您的回答很有用,但并没有完全解决问题。如果我将其标记为“已解决”,那么查看它的人就会减少,我获得其他有用答案的机会也会减少。你是对的,使用可重现的示例会更好,但是我的脚本和它加载的库非常复杂,所以我需要相当长的时间才能构建一个可以在这里发布的示例。
猜你喜欢
  • 2021-01-13
  • 1970-01-01
  • 2021-01-22
  • 1970-01-01
  • 1970-01-01
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多