fread指定列内的分隔符
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了fread指定列内的分隔符相关的知识,希望对你有一定的参考价值。
我试图解析一个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
答案
这似乎有效:
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
另一答案
这是一种使用来自“tidyr”的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,}
)。这不是在()
,所以我们不需要将其提取到新列中。 - 这组空格可以跟随其他任何东西(
(.*)
)。这是在()
,所以捕获并将其提取到一个新列。
我还使用了第一个“x”值来提取原始列名。
这是它的样子:
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, }")))
另一答案
逐行读入您的文本文件:
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)
以上是关于fread指定列内的分隔符的主要内容,如果未能解决你的问题,请参考以下文章