【问题标题】:R: Reformatting data fileR:重新格式化数据文件
【发布时间】:2015-07-16 20:37:24
【问题描述】:

我怀疑是一个简单的数据重新格式化问题。数据文件 (txt) 的结构是在单独的行上使用观察编号,

1
45 65
78 56
2
89 34
39 55

想要的输出是,

1 45 65
1 78 56
2 89 34
2 39 55

我们将不胜感激有关如何进行转换的建议。谢谢。

【问题讨论】:

    标签: r reformatting


    【解决方案1】:

    我们可以使用readLines 读取文件。创建一个索引变量并拆分“行”。移除列表元素的第一个元素,使用read.table读取文件,unnest

     lines <- readLines('file.txt')
     library(stringr)
     #remove leading/lagging spaces if any 
     lines <- str_trim(lines) 
     #create the index mentioned above based on white space 
     indx  <- !grepl('\\s+', lines)
     #cumsum the above index to create grouping
     indx1 <- cumsum(indx)
     #split the lines with and change the names of the list elements 
     lst <- setNames(split(lines, indx1), lines[indx])
     #Use unnest after reading with read.table 
     library(tidyr)
     unnest(lapply(lst, function(x) read.table(text=x[-1])), gr)
     #   gr V1 V2
     #1  1 45 65
     #2  1 78 56
     #3  2 89 34
     #4  2 39 55
    

    或者我们可以使用Map from base R 方法

     do.call(rbind,Map(cbind, gr=names(lst), 
                 lapply(lst, function(x) read.table(text=x[-1]))))
    

    【讨论】:

    • 谢谢。按预期工作。
    • @ksing 好的,感谢您更新。所以,我猜这个错误是固定的?
    • 上面提供的答案适用于 tidyr 0.2.0,但似乎在 0.3.0 下因 object 'gr' not found 而失败。也许有一个快速的解决办法?谢谢。
    • @ksing 感谢您的反馈。我能够在 0.3.0 中重现该问题。这可能是一个错误。我们可以使用base R 来做到这一点。即do.call(rbind,Map(cbind, gr=names(lst), lapply(lst, function(x) read.table(text=x[-1]))))
    • 谢谢。经过一番搜索,我今天早些时候更新了lst2 &lt;- lapply(lst, function(x) read.table(text=x[-1]))out &lt;- Reduce(rbind, Map(cbind, lst2, gr = names(lst2))),但将使用上述内容。顺便说一句,这个解决方案在 gr 上按数字排序(即 1-2-3-4...N),而 tidyr 解决方案将作为字符串排序(?)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 2017-11-12
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    相关资源
    最近更新 更多