【问题标题】:text file to dataframe with a list column文本文件到带有列表列的数据框
【发布时间】:2016-08-02 05:14:03
【问题描述】:

我正在尝试读取这样的文本文件:

exp1 sample1 2 5  
exp2 sample1 2 3 5 7
exp1 sample2 1 2 6

到具有如下列表列的数据框:

tibble(exp = c("exp1", "exp2", "exp3"), 
       sample = c("sample1","sample1","sample2"), 
       listdata = list(list(2,5), list(2,3,5,7), list(1,2,6)))

# A tibble: 3 x 3
    exp  sample   listdata
  <chr>   <chr>     <list>
1  exp1 sample1 <list [2]>
2  exp2 sample1 <list [4]>
3  exp3 sample2 <list [3]>

目的是利用前两列的元数据对列表进行选择和操作。

我可以将行作为列表读取,但不知道如何分隔元数据:

listdata <- read_lines("list_c_data.txt") %>% strsplit(., " ") %>% tibble()

有什么建议吗?我可能需要逐行读取文件,因为观察次数可能> 100000,并且每行中列表的长度可能> 1000

【问题讨论】:

    标签: r list dataframe dplyr


    【解决方案1】:

    我们使用read.table/read.csvfill = TRUE 读取文件,然后gather(来自tidyr)数据集的倒数第三列将其重塑为“长”格式,按“V1”和“分组” V2',我们将summarise 'Val' 作为list 然后rename 列(如有必要)。

    library(dplyr)
    library(tidyr)
    df1 <- read.table("yourfile.txt", header=FALSE, fill = TRUE)
    gather(df1, Var, Val, V3:ncol(df1), na.rm = TRUE) %>%
             group_by(V1, V2) %>% 
             summarise(Val = list(Val)) %>%
             rename(exp=V1, sample = V2, listdata = Val)             
    

    或者我们可以scan 读取行,strsplit 按空格,将 'lst' 中的元素(过滤掉第一个和第二个)转换为 numeric 而我们 rbind 将第一个和第二个元素转换为data.frame 并创建“lst2”作为第三列。

    l1 <- trimws(scan("yourfile.txt", what ="", sep="\n", quiet=TRUE))
    lst <- strsplit(l1, " ")
    lst2 <- lapply(lst, function(x) as.numeric(x[-(1:2)]))
    d1 <- setNames(do.call(rbind.data.frame, lapply(lst, 
                    function(x) x[1:2])), c("exp", "sample"))
    d1$listdata <- lst2
    

    【讨论】:

    • 非常感谢。两个都试过了。第一种方法对我来说更容易理解,但read.table 似乎不能很好地处理不同的列表长度——它会截断较长的列表并开始一个新行。我猜它使用前几行来确定要填充的最大列数。你的第二种方法效果很好。只是我不熟悉基本功能——它们看起来不像我能记住/掌握的东西:-(
    • @Dong 我尝试了您的示例并使用了fill=TRUE,并且能够获得预期的输出。
    • 是的,它适用于示例,但如果列表长度为“2、4、3、4、9、3”,则会失败。列表长度为“9”的行将被折叠到下一行。我认为这是read.table 用来确定列数而不到文件末尾的算法。
    • 第二种方法的一个缺点是lst 的大小变得比原始文件大小大得多(~10X)。一旦文件变大,它可能会成为一个问题。
    • @Dong 在fread 中有fill 选项,来自data.table,应该很快
    猜你喜欢
    • 2021-07-26
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多