fread指定列内的分隔符

时间:2017-12-21 17:54:31

标签: r dataset

我正在尝试解析一个2列列表,该列列表使用列的多个空格和列中单词的单个空格分隔。我没有尝试过将数据成功分成两列。我该怎么做?

library(data.table)
item.ids<-fread("http://eve-files.com/chribba/typeid.txt",sep2=" ")

数据集示例:

typeID      typeName
----------- ----------------------------------------
0           #System
2           Corporation
3           Region
4           Constellation
5           Solar System

3 个答案:

答案 0 :(得分:1)

这是一种使用来自&#34; tidyr&#34;的extract的方法。这应该很容易理解。

首先,我们读取数据,并检查前几行和最后几行。检查后,我们发现数据值来自第3到22384行。

x <- readLines("http://eve-files.com/chribba/typeid.txt")
# Check out the data
head(x) # Let's get rid of the first two lines...
tail(x) # ... and the last 3

在提取阶段,我们基本上都在寻找:

  • 一组数字 - 可以有不同的长度(([0-9]+))。它位于()中,因此请将其捕获并提取到新列。
  • 数字后面应加2个或更多个空格([ ]{2,})。那不在(),所以我们不需要将其提取到新列中。
  • 空格集后面可以跟任何其他内容((.*))。这是()中的内容,因此请将其捕获并提取到新列中。

我还使用了&#34; x&#34;的第一个值。提取原始列名称。

这就是它的样子:

library(tidyverse)
data_frame(V1 = x[3:(length(x)-3)]) %>%
  extract(V1, into = scan(text = x[1], what = ""), regex = "([0-9]+)[ ]{2,}(.*)")
# # A tibble: 22,382 x 2
#    typeID           typeName
#  *  <chr>              <chr>
#  1      0            #System
#  2      2        Corporation
#  3      3             Region
#  4      4      Constellation
#  5      5       Solar System
#  6      6    Sun G5 (Yellow)
#  7      7    Sun K7 (Orange)
#  8      8 Sun K5 (Red Giant)
#  9      9      Sun B0 (Blue)
# 10     10     Sun F0 (White)
# # ... with 22,372 more rows

或者

data_frame(V1 = x[3:(length(x)-3)]) %>%
  separate(V1, into = scan(text = x[1], what = ""), sep = "[ ]{2,}", 
           extra = "merge", convert = TRUE)

另一种方法可能是将strsplit[ ]{2, }一起用作分割值。 do.call(rbind, ...)之后会成为惯用词,但您可能只希望过滤分割后产生两个值的情况。

do.call(rbind, Filter(function(z) length(z) == 2, strsplit(x, "[ ]{2, }")))

答案 1 :(得分:1)

这似乎有效:

library(readr)
url = "http://eve-files.com/chribba/typeid.txt"
df = read_fwf(url, fwf_empty(url), skip = 2)
colnames = read_table(url, n_max = 1)
names(df) = names(colnames)
df = na.omit(df)

dim(df)
# [1] 22382     2
summary(df)
 #    typeID         typeName        
 # Min.   :     0   Length:22382      
 # 1st Qu.: 13986   Class :character  
 # Median : 22938   Mode  :character  
 # Mean   : 53827                     
 # 3rd Qu.: 30209                     
 # Max.   :368620    

答案 2 :(得分:0)

逐行读入您的文本文件:

l <- list()
fileName <- "http://eve-files.com/chribba/typeid.txt"
conn <- file(fileName,open="r")
linn <-readLines(conn)
for (i in 1:length(linn)){
   l[i] <- list(linn[i])
}
close(conn)

创建所有条目的列表:

l_new <- list()
for(p in 1:length(l)) {

    new_vec <- unlist(strsplit(gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", l[[p]], perl=TRUE), " "))

    if(!is.na(new_vec[4])) { 
        new_vec_t <- paste(new_vec[2], new_vec[3], new_vec[4])
    } 
    else if (!is.na(new_vec[3])) {
        new_vec_t <- paste(new_vec[2], new_vec[3])
    } 
    else {
        new_vec_t <- paste(new_vec[2])
    }

    l_new[p] <- list(c(new_vec[1], new_vec_t))

}

将您的列表转换为数据框:

l_new_frame <- data.frame(do.call('rbind', l_new))

l_new_frame <- l_new_frame[-c(1,2),]
names(l_new_frame) <- c('typeID', 'typeName')

检查结果:

print(l_new_frame[1:100,], row.names = FALSE)

enter image description here