【问题标题】:Perform calculation on each row of a single column from data frame对数据框中单列的每一行执行计算
【发布时间】:2018-01-03 06:13:31
【问题描述】:

我有一个数据框(data):

  sample chrom     pos ref alt tri trans decomposed_tri grouped_trans    type    feature       gene
1 1    1  659105   G   A CGT   G>A            ACG           C>T somatic     intron         ds
2 1    1 1227592   A   G CAC   A>G            GTG           T>C somatic     intron    CG42329
3 1    1 1775341   T   G CTG   T>G            CTG           T>G somatic intergenic intergenic
4 1    1 1775552   T   C GTT   T>C            GTT           T>C somatic intergenic intergenic
5 1    1 1812639   T   G GTG   T>G            GTG           T>G somatic intergenic intergenic
6 1    1 1812641   G   A GGA   G>A            TCC           C>T somatic intergenic intergenic

以及基因长度列表 (gene_lengths):

$`128up`
[1] 1553

$`14-3-3epsilon`
[1] 8019

$`14-3-3zeta`
[1] 10010

$`140up`
[1] 1385

$`18SrRNA-Psi:CR41602`
[1] 1974

$`18SrRNA-Psi:CR45861`
[1] 1933

我想:
a) 计算给定基因长度(gene_lengths)和长度基因组 (137547960)
b) 计算我们实际看到每个基因的次数 hit_genes<-table(data$gene)
c) 计算 a 的比率观察/预期 fc<-gene_lengths[g]/gene_expect
d) 将此作为数据框返回

这就是我正在做的事情:

snv_count<-nrow(data) # total number of observations
hit_genes<-table(data$gene) # the number of times I find each gene in my data
cat("gene", "observed", "expected", "fc", "\n")

for (g in levels(data$gene)) {
    genefraction<-gene_lengths[[g]]/137547960
    gene_expect<-snv_count*(genefraction)
    fc<-gene_lengths[g]/gene_expect
    cat(g, hit_genes[g], gene_expect, fc, "\n")
  }

gene observed expected fc
128up 5 1.493344 3.348189 
18SrRNA-Psi:CR45861 3 0.5076489 5.909596 
C442219 4 0.03778505 105.862 

这行得通。但是,我在一个函数中运行它,并且想要返回一个数据框,如何在 for 循环中逐行构建一个数据框?我尝试在循环之前初始化一个空数据框:

df <- data.frame(gene = character(), observed = numeric(), expected = numeric(), fc = numeric())

然后在循环中逐行构建:

enriched <- rbind(df, data.frame(gene = g, observed = hit_genes[g], expected = gene_expect, fc = fc))

但我收到以下错误:

Error in data.frame(gene = g, observed = hit_genes[g], expected = gene_expect,  : 
  arguments imply differing number of rows: 1, 0

另一个问题是 - 我应该使用ddply 来实现这一点而不是循环吗?

【问题讨论】:

  • 你能给我们提供一些使用dput的示例数据吗?

标签: r plyr


【解决方案1】:

也许是?lapply。 (未经测试。)

enriched <- lapply(levels(data$gene), fun)
enriched <- do.call(rbind, enriched)
enriched

# 'fun' returns a list with four members
fun <- function(g) {
    genefraction<-gene_lengths[[g]]/137547960
    gene_expect<-snv_count*(genefraction)
    fc<-hit_genes[g]/gene_expect
    list(gene = g, observed = hit_genes[g], expected = gene_expect, fc = fc)
}

请注意,这假定函数 fun 中引用的对象是可用的,即在全局环境中。

【讨论】:

  • 这太棒了——如何输出多列?当我运行它时,我只得到 fc 列作为输出。
  • 你可以让函数fun返回你想要的任何东西,但是如果你返回多个列,do.call技巧可能不起作用。要构造enriched,您可能需要其他东西。究竟什么取决于函数的返回对象。我将编辑我的答案,以提示您 fun 可以返回什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 2019-11-07
  • 2022-01-07
  • 2020-02-12
  • 2021-06-12
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多