R中的txt文件导入问题

问题描述

问题是txt文件本身的格式似乎不正确,但是一旦它们处于R环境中就无法将任何数据转换为可行的格式(即每列只有一个条目的数据框),那么我什么也无法工作)。

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

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

给出所描述的不良结果(单列,所有值都用空格或制表符分隔为长字符串)

我也尝试过:

indivs<-lapply(files,sep=" ",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

解决方法

//更新:
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(.,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))

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

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

files_headers <- file_ls %>%
  map(~read.table(.,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)
  )