如何将包含 S4 对象的大列表写为 CSV 文件?

How to write a large list with S4 objects as a CSV file?

我有 运行 的代码并输出一个大列表。我坚持将输出写入文件,因为我不断收到不同的错误,所以我无法以通常用于数据帧的任何方式写入文件。

我使用的代码和数据是这样的:

library(GeneOverlap)
library(dplyr)
library(stringr)

dataset1 <- structure(list(Gene = c("Gene1", "Gene1", "Gene2", "Gene3", "Gene3.", 
"Gene3"), Gene_count = c(5L, 5L, 3L, 16L, 16L, 16L), Phenotype = c("Phenotype1", 
"Phenotype2", "Phenotype1", "Phenotype6", "Phenotype2", "Phenotype1"
)), row.names = c(NA, -6L), class = c("data.table", "data.frame"
))


dataset2 <- structure(list(Gene = c("Gene1", "Gene1", "Gene4", "Gene2", "Gene6", 
"Gene7"), Gene_count = c(10L, 10L, 4L, 17L, 3L, 2L), Phenotype = c("Phenotype1", 
"Phenotype2", "Phenotype1", "Phenotype6", "Phenotype2", "Phenotype1"
)), row.names = c(NA, -6L), class = c("data.table", "data.frame"
))

d1_split <- split(dataset1, dataset1$Phenotype)
d2_split <- split(dataset2, dataset2$Phenotype)

# this should be TRUE in order for Map to work correctly
all(names(d1_split) == names(d2_split))

tests <- Map(function(d1, d2) {
  go.obj <- newGeneOverlap(d1$Gene, d2$Gene, genome.size = 1871)
  return(testGeneOverlap(go.obj))
}, d1_split, d2_split)

然后我想将 tests 大列表对象写到一个文件中——理想情况下,将上面代码中每个 Phenotype 的 p 值作为一列。但是我不断收到与以下任何一项相关的各种错误:

library(Matrix)
library(data.table)
lstData <- Map(as.data.frame, tests)
Error in as.data.frame.default(dots[[1L]][[1L]]) : 
  cannot coerce class ‘structure("GeneOverlap", package = "GeneOverlap")’ to a data.frame
dfrData <- rbindlist(lstData)
Error in rbindlist(lstData) : object 'lstData' not found
Error in fwrite(tests, "list.csv") : 
  Column 1's type is 'S4' - not yet implemented in fwrite.
library(data.table)
outputfile <- "test.csv" #output file name
sep <- "," #define the separator (related to format of the output file)
for(nam in names(tests)){
  fwrite(list(nam), file=outputfile, sep=sep, append=T) #write names of the list elements
  ele <- tests[[nam]]
  if(is.list(ele)) fwrite(ele, file=outputfile, sep=sep, append=T, col.names=T) else fwrite(data.frame(matrix(ele, nrow=1)), file=outputfile, append=T) #write elements of the list
  fwrite(list(NA), file=outputfile, append=T) #add an empty row to separate elements
}

Error in as.vector(data) : 
  no method for coercing this S4 class to a vector

我一直在努力理解 S4 对象,但我是 R 初学者 - 我可以使用哪些函数或包来写出我的 tests 对象?示例数据包含在上面 运行 所有代码中。

GeneOverlap 包有几个 get* 函数用于访问测试结果统计。您可以将其与 tidyverse 结合使用以创建整洁的 table 结果:

results <- tibble(pheno = names(tests), tests = tests) %>% 
  rowwise() %>% 
  mutate(
    across(tests, 
           .fns = list(tested = getTested, pval = getPval, OR = getOddsRatio, jaccard = getJaccard), 
           .names = '{.fn}')
  ) %>% 
  select(-tests) # drop test object column

  pheno      tested    pval    OR jaccard
  <chr>      <lgl>    <dbl> <dbl>   <dbl>
1 Phenotype1 TRUE   0.00481  410.   0.2  
2 Phenotype2 TRUE   0.00214 1302.   0.333
3 Phenotype6 TRUE   1          0    0    

然后您可以使用 write_csv 或类似的方法保存此数据框。

CSV格式很简单:它是一个文本文件,存储“comma-separated个变量”,其中变量都是字符串。如果格式正确,一些字符串将被转换为数字。

S4 对象是非常复杂的东西,不容易存储为字符串。

因此,要将 S4 对象放入 CSV 文件中,您需要将其转换为一个或多个字符串。您可以使用 paste(dput(x), collapse="")x 转换为稍后可以恢复为 S4 对象的字符串,但无法访问存储在 x 中的内容。在将它们存储为 CSV 文件之前,您需要使用类似 @jdobres 的方法来提取内容,然后您可能无法从文件中恢复对象。

如果确实需要恢复 S4 对象,请使用列表上的 saveRDS() 将完整列表存储在 .rds 文件中。它可以被 R 读取,但不能被其他软件读取。