【问题标题】:Applying a function over multiple df that are NOT combined in a list对未组合在列表中的多个 df 应用函数
【发布时间】:2019-10-09 13:41:19
【问题描述】:

我知道 apply/map 可以在数据框列表上运行函数,但我的问题是该函数使用数据框的名称来创建 col 名称,并且在 dfs 列表上使用它不起作用.有没有一种方法可以在多个 DF 上自动运行该函数而不将它们组合在一个列表中?

或者,我也可以更改函数,使其从列表对象中获取名称,但到目前为止我也失败了。

也许有人有解决方案? 非常感谢!

示例数据

p.vals <- seq(from=0, to=1, by=.0001)
logFCs <- seq(from=0, to=4, by=.1)
diffEx_proteins <- data.frame(protein=LETTERS[1:1000],
                      adj.P.Val=sample(p.vals, size=1000, replace=TRUE),
                      logFC=sample(logFCs, size=1000, replace=TRUE))

diffEx_proteins_2 <- data.frame(protein=LETTERS[1:1000],
                      adj.P.Val=sample(p.vals, size=1000, replace=TRUE),
                      logFC=sample(logFCs, size=1000, replace=TRUE))

list <- list(group1 = diffEx_proteins, group2 = diffEx_proteins_2)

功能

mark_significants_p.05and.001_fc1 <- function(comparison){
dat <- comparison
name <- deparse(substitute(comparison))
dat[,paste(name,"up_0.05", sep = "_")] <- dat$adj.P.Val <= 0.05 & dat$logFC >= 1
dat[,paste(name,"down_0.05", sep = "_")] <- dat$adj.P.Val <= 0.05 & dat$logFC <= -1
dat[,paste(name,"up_0.001", sep = "_")] <- dat$adj.P.Val <= 0.001 & dat$logFC >= 1
dat[,paste(name,"down_0.001", sep = "_")] <- dat$adj.P.Val <= 0.001 & dat$logFC <= -1
dat[,paste(name,"reg_0.05", sep = "_")] <- dat$adj.P.Val <= 0.05 & abs(dat$logFC) >= 1
dat[,paste(name,"reg_0.001", sep = "_")] <- dat$adj.P.Val <= 0.001 & abs(dat$logFC) >= 1
return(dat)
}

map(list, mark_significants_p.05and.001_fc1) 导致名称以 [[1]] 开头的列,但我想在其中包含 df 名称。

谢谢! 塞巴斯蒂安

【问题讨论】:

  • 我你使用dplyr::lst()你会得到一个表的列表,其中包含被命名为表本身的项目,然后你可以改变你的功能,这是可能的吗?否则你将不得不循环表名并使用eval(bquote(mark_significants_p.05and.001_fc1(.(as.symbol(tbl_name)))))之类的东西,但我希望你能避免这种情况
  • 另外我建议您避免将列表命名为list,因为将列表和函数命名为相同会很混乱

标签: r list function dataframe apply


【解决方案1】:

您可以使用imap 传递列表及其名称

mark_significants_p.05and.001_fc1 <- function(comparison, name){
    dat <- comparison
    dat[,paste(name,"up_0.05", sep = "_")] <- dat$adj.P.Val <= 0.05 & dat$logFC >= 1
    dat[,paste(name,"down_0.05", sep = "_")] <- dat$adj.P.Val <= 0.05 & dat$logFC <= -1
    dat[,paste(name,"up_0.001", sep = "_")] <- dat$adj.P.Val <= 0.001 & dat$logFC >= 1
    dat[,paste(name,"down_0.001", sep = "_")] <- dat$adj.P.Val <= 0.001 & dat$logFC <= -1
    dat[,paste(name,"reg_0.05", sep = "_")] <- dat$adj.P.Val <= 0.05 & abs(dat$logFC) >= 1
    dat[,paste(name,"reg_0.001", sep = "_")] <- dat$adj.P.Val <= 0.001 & abs(dat$logFC) >= 1
   return(dat)
}


purrr::imap(list, mark_significants_p.05and.001_fc1)

imapmap2 相同,通过列表名称传递

purrr::map2(list, names(list), mark_significants_p.05and.001_fc1)

【讨论】:

  • 我的理解是 OP 想要名为“diffEx_proteins”等的对象,而不是“group1”等,但我可能没有正确理解
  • 酷,这实际上解决了它!使用列表的名称进行命名是一个很好的解决方法:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 2016-06-27
  • 1970-01-01
相关资源
最近更新 更多