R中的txt文件导入问题

txt file import issues in R

问题是 txt 文件本身似乎格式不正确,但是一旦它们在 R 环境中将数据转换为可用格式(即具有一个条目的数据框),我就无法使用任何东西每列)。

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

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

给出了所描述的不希望的结果(所有值由 space 分隔的单列或制表符作为长字符串)

我也试过:

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 跟踪器,这些跟踪器容易出现错误读数,这会导致 number/header 列出现差异,因为当不确定位置时它不会给出尽可能多的值(参见数据结构也结束)。它给出了这样的条目:

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

// 更新:
OP的问题简单地解决了:

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

原始答案:

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

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))

// 更新:
考虑到 multi-line 数据的问题,这是一次返工。 这一次,代码逐行读取每个文件,然后根据是否找到 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)
  )