【问题标题】:Importing data into R, when data isn't formatted as a table当数据未格式化为表格时,将数据导入 R
【发布时间】:2016-05-11 05:48:22
【问题描述】:

我有以下带有 9796 行的制表符分隔的 .txt 文件:

https://www.dropbox.com/s/fnrbmaw8odm2rqs/Kommunale_N%C3%B8gletal.txt?dl=0

我想将文件读入 R,但该文件不是经典表格格式。相反,每个感兴趣的变量有 279 行和 16 列,其中第一行定义变量名称,前 2 列定义城市名称和代码,接下来的 14 列定义 1993-2006 年。每个变量由一个空白行分隔。该文件包含 35 个变量。

我想将数据读入data.frame,但其中一列用于城市名称、城市代码和年份,而一列用于 35 个变量中的每一个。

如果您不习惯点击链接或喜欢较小的样本,以下说明了数据集(2 个变量和 3 年的观察):

Indbyggertal 1 januar
Københavns Kommune     101    466129    467253  471300
Frederiksberg Kommune  147    87173     87466   88002
Ballerup Kommune       151    45427     45293   45356

Andel 0-17-årige
Københavns Kommune     101    14.0      14.1    14.4
Frederiksberg Kommune  147    12.4      12.5    12.6
Ballerup Kommune       151    21.2      21.1    21.3

preferred out 的前 3 行应如下所示:

Municipality name      Municipality code    Year    Indbyggertal 1 januar   Andel 0-17-årige    …   Ældreudg (netto) pr 65+/67+-årig
Københavns Kommune     101                  1993    466129                  14                      35350
Frederiksberg Kommune  147                  1993    87173                   12.4                    33701
Ballerup Kommune       151                  1993    45427                   21.2                    31126

【问题讨论】:

  • 你能展示你尝试过的东西吗?你的输出应该是什么样子?
  • 我刚刚尝试使用具有不同设置的read.table,但我认为我需要使用某种applyfor 循环。我将尝试说明首选输出。
  • 你应该包含你的数据样本
  • @stasg 我已在链接中包含我的所有数据。是这个意思吗?
  • @stasg:好的,我会尝试提供一个说明性示例。

标签: r dataframe read.table


【解决方案1】:

可能有更多的方法可以做到这一点,但我在下面使用的技巧是将所有数据作为文本读取,然后确定新块开始的位置,最后循环读取所有块并将它们存储在一个list:

lines <- readLines("Kommunale_Nøgletal.txt", encoding = "latin1")

# Find empty lines; these start a new block
start <- c(0, grep("^[\t]+$", lines))

# Read titles
headers <- lines[start + 1]
headers <- gsub("\t", "", headers)

# Determine beginnen and ending of data blocks
begin <- start + 2
end   <- c(start[-1]-1, length(lines))

# Read each of the data blocks into a list
data <- vector(mode = "list", length(headers))
for (i in seq_along(headers)) {
  block <- lines[begin[i]:end[i]]
  data[[i]] <- read.table(textConnection(block), sep="\t", na.strings=c("U","M","-"))
}
names(data) <- headers

在这之后在每个数据集中设置正确的标题应该很简单,然后组合成一个数据。可以使用dplyr 包中的rbind_all 完成。下面是一个例子:

# Set columnnames in data
# Add variable name to data
for (i in names(data)) {
  names(data[[i]]) <- c("municipality", "code", paste0("Y", 1993:2006))
  data[[i]]$var = i
}

# Merge the different datasets into one data.frame
library(dplyr)
data <- rbind_all(data)

# Transpose the data
library(reshape2)
m <- melt(data, id.vars = c("municipality", "code", "var"))
res <- dcast(m, municipality + code + variable ~ var)

# Fix the year variable
names(res)[3] <- "year"
res$year <- as.numeric(gsub("Y", "", res$year))

【讨论】:

  • 谢谢,看起来不错,但是当我尝试运行您的代码时,它在第一行失败,说最后一行不完整。你能让它工作吗?
  • 我猜这只是一个警告!
  • @dikesh 是对的:您通常可以忽略此警告。这只是它所说的:文件中的最后一行不以换行符结尾(输入)。有时这可能表明读取文件时使用了错误的编码。
  • 啊是的 - 当然。我让它工作,我现在尝试将列表转换为dataframe。我将看看dplyr 中的rbind_all 函数。
  • @JanvanderLaan:我尝试过使用rbind_all,但我看不到如何转置块,以便将每个块的最后 16 个变量变成行(16 个变量中的每一个从 1993 年到 2006 年),每个块构成 data.frame 中的一个变量。知道该怎么做吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
  • 2017-06-17
  • 1970-01-01
相关资源
最近更新 更多