首页 > 解决方案 > 在 R 中读取文本文件中的分组

问题描述

我有一个包含许多分组部分的文本文件,如下所示(每组中的数字显然不同)。我想抓取每个分组中的所有 X、Y 和 Z 列并将它们放入数据框中。我怎么能这样做?我还想添加一个指示列来标识这些行来自哪个分组。

这是文本文件外观的基本布局...

Start Date:                 02/05/2020
Start Time:                 16:00:14

  Time         X     Y     Z
============   ===== ===== =====
000:00:00.05    3.50  9.00  8.50
000:00:00.10    3.50  8.50  9.00
000:00:00.15    5.00  8.00  9.50
000:00:00.20    5.00  9.00  8.50
000:00:00.25    5.00  9.00  6.50
000:00:00.30    3.50  9.50  7.00


Start Date:                 02/05/2020
Start Time:                 16:00:14

  Time         X     Y     Z
============   ===== ===== =====
000:00:00.05    3.50  9.00  8.50
000:00:00.10    3.50  8.50  9.00
000:00:00.15    5.00  8.00  9.50
000:00:00.20    5.00  9.00  8.50
000:00:00.25    5.00  9.00  6.50
000:00:00.30    3.50  9.50  7.00


Start Date:                 02/05/2020
Start Time:                 16:00:14

  Time         X     Y     Z
============   ===== ===== =====
000:00:00.05    3.50  9.00  8.50
000:00:00.10    3.50  8.50  9.00
000:00:00.15    5.00  8.00  9.50
000:00:00.20    5.00  9.00  8.50
000:00:00.25    5.00  9.00  6.50
000:00:00.30    3.50  9.50  7.00

我尝试使用此代码,但只能获得每个分组的第一行...

export <- list.files(path=wd, pattern = "one.Export")
options(warn=-1)
dat <- readLines(export)
x_dat <- read.table(text = dat[grep("Start Time:", dat) + 4])[,2:4]

如果我添加行长度,我会返回 NA ......

x_dat <- read.table(text = dat[grep("Start Time:", dat) + 4])[1:5,2:4]

有什么建议么?

标签: r

解决方案


这种文本解析的问题在于,必须依赖于问题中指定的确切格式的文本。

这适用于您的示例,但可能必须针对您自己的真实数据进行修改:

library(tidyverse)

  readLines("~/data.txt")  %>%          # Read file into a vector of strings
  paste(collapse = "\n") %>%            # Stick them together with newlines
  strsplit("Start Date: +") %>%         # Split them into groups at the keyword
  unlist %>%                            
  `[`(-1) %>%    # Remove the empty first element
  lapply(function(x) unlist(strsplit(x, "\n"))) %>%         # carve at line breaks
  lapply(function(x) grep("\\d", x, value = TRUE)) %>%      # keep only rows with numbers
  lapply(function(x) strsplit(x, " +")) %>%                 # carve at spaces
  lapply(function(x) cbind(rep(paste(x[[1]], x[[2]][3]), length(x) - 2),
                           do.call(rbind, x[-c(1:2)]))) %>% # Bind into rows and add labels
  {do.call(rbind, .)} %>%                                   # Stick groups together
  as.data.frame() %>%
  setNames(c("Group_date", "Time", "X", "Y", "Z"))          # Make dataframe and name it
#>             Group_date         Time    X    Y    Z
#> 1  02/05/2020 16:00:14 000:00:00.05 3.50 9.00 8.50
#> 2  02/05/2020 16:00:14 000:00:00.10 3.50 8.50 9.00
#> 3  02/05/2020 16:00:14 000:00:00.15 5.00 8.00 9.50
#> 4  02/05/2020 16:00:14 000:00:00.20 5.00 9.00 8.50
#> 5  02/05/2020 16:00:14 000:00:00.25 5.00 9.00 6.50
#> 6  02/05/2020 16:00:14 000:00:00.30 3.50 9.50 7.00
#> 7  02/05/2020 16:00:14 000:00:00.05 3.50 9.00 8.50
#> 8  02/05/2020 16:00:14 000:00:00.10 3.50 8.50 9.00
#> 9  02/05/2020 16:00:14 000:00:00.15 5.00 8.00 9.50
#> 10 02/05/2020 16:00:14 000:00:00.20 5.00 9.00 8.50
#> 11 02/05/2020 16:00:14 000:00:00.25 5.00 9.00 6.50
#> 12 02/05/2020 16:00:14 000:00:00.30 3.50 9.50 7.00
#> 13 02/05/2020 16:00:14 000:00:00.05 3.50 9.00 8.50
#> 14 02/05/2020 16:00:14 000:00:00.10 3.50 8.50 9.00
#> 15 02/05/2020 16:00:14 000:00:00.15 5.00 8.00 9.50
#> 16 02/05/2020 16:00:14 000:00:00.20 5.00 9.00 8.50
#> 17 02/05/2020 16:00:14 000:00:00.25 5.00 9.00 6.50
#> 18 02/05/2020 16:00:14 000:00:00.30 3.50 9.50 7.00

reprex 包(v0.3.0)于 2020-02-24 创建


推荐阅读