【问题标题】:txt file import issues in RR中的txt文件导入问题
【发布时间】:2020-09-08 10:51:23
【问题描述】:

问题是 txt 文件本身的格式似乎很差,但是一旦它们在 R 环境中将数据转换为可行的格式(即每列一个条目的数据框),我就无法工作)。

基本 R 函数 read.delim 将我的文本文件导入为单列(忽略分隔符,我不确定它是制表符还是空格)。我试过了:

indivs<-lapply(files, read.delim, sep="\t", header=T, na.strings = "NA")

它给出了所描述的不想要的结果(单列,所有值由空格或制表符分隔为长字符串)

我也试过了:

indivs<-lapply(files, read.delim, sep=" ", header=T, na.strings = "NA")

抛出:

Error in read.table(file = file, header = header, sep = sep, quote = quote,  : 
  more columns than column names

所以我认为至少第一个选项将文件放入 R 中,我可以从那里继续...

数据来自 GPS 跟踪器,这些跟踪器容易获得错误读数,这会导致列号/标题差异,因为当它不确定位置时它不会提供那么多值(另请参见末尾的数据结构)。它给出了这样的条目:

356   356  NotEnoughSats   0/2  19/12/12  13:40:11 

完整条目如下所示:

357   357          Valid   5/6  19/12/12  13:50:11  19/12/12  13:48:33.831    -97.169    -23.44309    151.91783        35.04    10.8         0.9             0.0        0.00

使用我实际设法导入文件的方法,我一直在尝试使用 dplyr::filtergrepl 的组合来删除具有错误读数的行,从而使我得到正确数量的标题名称和条目允许正确的read.delim 执行

我正在处理不同跟踪器的数据框列表,因此我希望有人能找到一种方法来使用 lapply 函数或类似函数应用求解,类似这样(不运行):

    cleaned.txts<-lapply(indivs, function(x){
  x%>%
    filter(grepl("Valid ", .))
})

这是来自其中一个数据框的示例:

    > head(indivs[1])
[[1]]
    Index.........Status..Sats..RTC.date..RTC.time..FIX.date......FIX.time...Delta.s......Latitude....Longitude..Altitude.m.....HDOP........eRes..Temperature.C...Voltage.V.
1       1  NotEnoughSats   0/0  19/12/10  02:30:06                            -81.140                                                                        0.0        0.00
2       2  NotEnoughSats   0/0  19/12/10  02:40:06                            -81.160                                                                        0.0        0.00
3       3  NotEnoughSats   0/2  19/12/10  02:50:08                            -81.180                                                                        0.0        0.00
4       4  NotEnoughSats   0/2  19/12/10  03:00:08                            -81.200                                                                        0.0        0.00
5       5  NotEnoughSats   0/1  19/12/10  03:10:08                            -81.220                                                                        0.0        0.00
6       6  NotEnoughSats   0/0  19/12/10  03:20:06                            -81.240                                                                        0.0        0.00
7       7  NotEnoughSats   0/2  19/12/10  03:30:08                            -81.260                                                                        0.0        0.00
8       8          Valid   3/3  19/12/10  03:40:11  19/12/10  03:38:49.720    -81.280    -23.44205    151.91308        30.00     2.9         0.0             0.0        0.00
9       9  NotEnoughSats   0/1  19/12/10  03:50:08                            -81.300                                                                        0.0        0.00
10     10  NotEnoughSats   0/0  19/12/10  04:00:06                            -81.320                                                                        0.0        0.00
11     11  NotEnoughSats   0/0  19/12/10  04:10:06                            -81.340                                                                        0.0        0.00
12     12  NotEnoughSats   0/2  19/12/10  04:20:08                            -81.360                                                                        0.0        0.00
13     13  NotEnoughSats   0/2  19/12/10  04:30:08                            -81.380                                                                        0.0        0.00
14     14  NotEnoughSats   0/1  19/12/10  04:40:08                            -81.400                                                                        0.0        0.00
15     15  NotEnoughSats   0/1  19/12/10  04:50:08                            -81.420                                                                        0.0        0.00
16     16  NotEnoughSats   0/1  19/12/10  05:00:08                            -81.440                                                                        0.0        0.00
17     17  NotEnoughSats   0/2  19/12/10  05:10:08                            -81.460                                                                        0.0        0.00
18     18  NotEnoughSats   0/2  19/12/10  05:20:08                            -81.480                                                                        0.0        0.00
19     19  NotEnoughSats   0/1  19/12/10  05:30:08                            -81.500                                                                        0.0        0.00
20     20  NotEnoughSats   0/1  19/12/10  05:40:08                            -81.520                                                                        0.0        0.00
21     21  NotEnoughSats   0/1  19/12/10  05:50:08                            -81.540                                                                        0.0        0.00
22     22          Valid   5/5  19/12/10  06:00:11  19/12/10  05:58:49.467    -81.533    -23.44350    151.91756        58.28     1.5         0.8             0.0        0.00
23     23  NotEnoughSats   0/1  19/12/10  06:10:08                            -81.580                                                                        0.0        0.00
24     24          Valid   3/3  19/12/10  06:20:11  19/12/10  06:18:49.400    -81.600    -23.43780    151.92362        58.35   219.5         0.0             0.0        0.00
25     25  NotEnoughSats   0/1  19/12/10  06:30:08                            -81.720                                                                        0.0        0.00

【问题讨论】:

  • 那么,具有良好读数的跟踪器可能仍会为您提供一个“短”标题,其列名少于数据中的实际值?
  • 请将示例文件添加为纯文本。
  • 也许用 data.table::fread 试试 cmd?比如:indivs&lt;-lapply(files, function(i){ fread(paste("grep Valid", i)})
  • 另外,如果你通过read.table(file, sep="", skip=1, header=F, fill=T),它还会崩溃吗?
  • 我想知道这是不是固定宽度的数据,在这种情况下看看read.fwf

标签: r filter grepl txt


【解决方案1】:

// 更新:
OP 的问题可以通过以下方式解决:

indivs <- lapply(files, read.table, sep="", header=T, fill=T)
indiv2 <- lapply(indivs, filter, Status=="Valid")

原始答案:

这行得通吗?
它对我有用,假设当您的跟踪器具有 GPS 读数时,最后添加了额外的列。否则,您可能希望在 map_dfr 中为每个文件修复列名。

library(dplyr)
library(purrr)

# only get the content of your files
files_content <- file_ls %>%
    map_dfr(~suppressWarnings(read.table(., sep='', header=F, skip=1, fill=T, na.strings = '')))

# only get the headers and keep the longest one
files_headers <- file_ls %>%
    map(~read.table(., sep='', header=F, nrows=1, na.strings = '')) %>%
    .[[which.max(sapply(., length))]]

# rename the columns with that header
files_final <- files_content %>%
    rename_with(.fn = ~as.character(files_headers[.x]), .cols = names(files_headers))

// 更新:
这是一个返工,考虑到您的多行数据问题。 这一次,代码逐行读取每个文件,然后根据找到ValidNotEnoughSats 之一分配real_line_id。然后,我们将文件中奇怪地拆分的行粘合在一起,然后我们才解析这些行。

library(readr)
library(tibble)
library(tidyr)
library(stringr)
library(dplyr)
library(purrr)

files_headers <- file_ls %>%
  map(~read.table(., sep='', header=F, nrows=1, na.strings = '')) %>%
  .[[which.max(sapply(., length))]] %>%
  as.character()

files_final <- file_ls %>%
  map_dfr(
    ~ tibble(
        line_raw = read_lines(., skip = 1)
      ) %>%
      mutate(
        validity = str_extract(line_raw, 'NotEnoughSats|Valid')
      ) %>%
      group_by(real_line_i = cumsum(!is.na(validity))) %>%
      summarise(
        parsed_line = paste(line_raw, collapse = ' ') %>%
          map(
            ~ strsplit(., split = '\\s+') %>%
              unlist() %>%
              setNames(., files_headers[seq_along(.)]) %>%
              as_tibble_row(.name_repair = 'universal')
          ),
        .groups = 'drop'
      ) %>%
      unnest(parsed_line)
  )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 2015-02-09
    相关资源
    最近更新 更多