将 ASCII 文本表格格式读入 R - 列表格式
Read ASCII text tabular format into R - list format
我正在尝试将 ASCI 文本文件读入 R。但是格式有点困难,分类变量显示为列表名称,而不是作为一个大型数据集中的变量。
以下是数据示例:https://cdiac.ess-dive.lbl.gov/ftp/ndp030/nation.1751_2014.ems
None 这些作品:
url <- 'https://cdiac.ess-dive.lbl.gov/ftp/ndp030/nation.1751_2014.ems'
read.table(url)
scan(url)
我可以 skip
到不同的线路,但这并不能解决问题。无论我从哪里开始,我都会遇到以下错误:
read.table()
抛出有关行号错误的错误
的元素。
scan()
到达第一部分时抛出错误
不同格式的文件:'expected real got xxx'
我想应该有一种简单的方法来导入它。显然,如果这种格式本身就很难处理,我将不得不阅读每一行然后编写一个函数将所有内容分开,那么不用担心。
关于处理这种格式的简单方法有什么想法吗?
p.s。我意识到此数据还有另一个来源,以整洁的格式 (https://cdiac.ess-dive.lbl.gov/trends/emis/tre_coun.html) 存储为 CSV。但是我现在想知道如何解决这个问题。
试试这个:
txt <- readLines('https://cdiac.ess-dive.lbl.gov/ftp/ndp030/nation.1751_2014.ems')
### demonstration of how to find the breaks:
nms <- grep("^[A-Za-z]+$", txt, value = TRUE)
head(nms)
# [1] "AFGHANISTAN" "ALBANIA" "ALGERIA" "ANDORRA" "ANGOLA"
# [6] "ANGUILLA"
tail(nms)
# [1] "VANUATU" "VENEZUELA" "YEMEN" "ZAMBIA" "ZANZIBAR" "ZIMBABWE"
主要工作:
lists <- by(txt, cumsum(grepl("^[A-Za-z]+$", txt)), function(s) {
ind <- grepl("^[0-9]", s)
if (any(ind)) cbind(cntry = s[1], read.table(text = as.character(s[ind]), stringsAsFactors = FALSE))
})
lists <- Filter(length, lists)
head(lists[[1]])
# cntry V1 V2 V3 V4 V5 V6 V7 V8 V9
# 1 AFGHANISTAN 1949 4 0 0 4 . 0 . 0
# 2 AFGHANISTAN 1950 23 0 18 6 0 0 0.00 0
# 3 AFGHANISTAN 1951 25 0 18 7 0 0 0.00 0
# 4 AFGHANISTAN 1952 25 0 17 9 0 0 0.00 0
# 5 AFGHANISTAN 1953 29 0 18 10 0 0 0.00 0
# 6 AFGHANISTAN 1954 29 0 18 12 0 0 0.00 0
全部合并:
alldat <- do.call(rbind, c(lists, list(stringsAsFactors = FALSE)))
head(alldat)
# cntry V1 V2 V3 V4 V5 V6 V7 V8 V9
# 1.1 AFGHANISTAN 1949 4 0 0 4 . 0 . 0
# 1.2 AFGHANISTAN 1950 23 0 18 6 0 0 0.00 0
# 1.3 AFGHANISTAN 1951 25 0 18 7 0 0 0.00 0
# 1.4 AFGHANISTAN 1952 25 0 17 9 0 0 0.00 0
# 1.5 AFGHANISTAN 1953 29 0 18 10 0 0 0.00 0
# 1.6 AFGHANISTAN 1954 29 0 18 12 0 0 0.00 0
tail(alldat)
# cntry V1 V2 V3 V4 V5 V6 V7 V8 V9
# 160.93 ZIMBABWE 2009 1528 0 455 977 0 95 0.11 6
# 160.94 ZIMBABWE 2010 2121 0 481 1531 0 109 0.15 7
# 160.95 ZIMBABWE 2011 2608 0 888 1584 0 136 0.18 8
# 160.96 ZIMBABWE 2012 2125 0 1006 917 0 201 0.15 9
# 160.97 ZIMBABWE 2013 3184 0 1119 1902 0 162 0.21 9
# 160.98 ZIMBABWE 2014 3278 0 1005 2097 0 177 0.22 9
(这也可以用 dplyr::bind_rows
或 data.table::rbindlist
来完成。)
实际的列名对于 R 来说有点冗长和不标准,我会留给你想出有意义的 colnames
。
我正在尝试将 ASCI 文本文件读入 R。但是格式有点困难,分类变量显示为列表名称,而不是作为一个大型数据集中的变量。
以下是数据示例:https://cdiac.ess-dive.lbl.gov/ftp/ndp030/nation.1751_2014.ems
None 这些作品:
url <- 'https://cdiac.ess-dive.lbl.gov/ftp/ndp030/nation.1751_2014.ems'
read.table(url)
scan(url)
我可以 skip
到不同的线路,但这并不能解决问题。无论我从哪里开始,我都会遇到以下错误:
read.table()
抛出有关行号错误的错误 的元素。scan()
到达第一部分时抛出错误 不同格式的文件:'expected real got xxx'
我想应该有一种简单的方法来导入它。显然,如果这种格式本身就很难处理,我将不得不阅读每一行然后编写一个函数将所有内容分开,那么不用担心。
关于处理这种格式的简单方法有什么想法吗?
p.s。我意识到此数据还有另一个来源,以整洁的格式 (https://cdiac.ess-dive.lbl.gov/trends/emis/tre_coun.html) 存储为 CSV。但是我现在想知道如何解决这个问题。
试试这个:
txt <- readLines('https://cdiac.ess-dive.lbl.gov/ftp/ndp030/nation.1751_2014.ems')
### demonstration of how to find the breaks:
nms <- grep("^[A-Za-z]+$", txt, value = TRUE)
head(nms)
# [1] "AFGHANISTAN" "ALBANIA" "ALGERIA" "ANDORRA" "ANGOLA"
# [6] "ANGUILLA"
tail(nms)
# [1] "VANUATU" "VENEZUELA" "YEMEN" "ZAMBIA" "ZANZIBAR" "ZIMBABWE"
主要工作:
lists <- by(txt, cumsum(grepl("^[A-Za-z]+$", txt)), function(s) {
ind <- grepl("^[0-9]", s)
if (any(ind)) cbind(cntry = s[1], read.table(text = as.character(s[ind]), stringsAsFactors = FALSE))
})
lists <- Filter(length, lists)
head(lists[[1]])
# cntry V1 V2 V3 V4 V5 V6 V7 V8 V9
# 1 AFGHANISTAN 1949 4 0 0 4 . 0 . 0
# 2 AFGHANISTAN 1950 23 0 18 6 0 0 0.00 0
# 3 AFGHANISTAN 1951 25 0 18 7 0 0 0.00 0
# 4 AFGHANISTAN 1952 25 0 17 9 0 0 0.00 0
# 5 AFGHANISTAN 1953 29 0 18 10 0 0 0.00 0
# 6 AFGHANISTAN 1954 29 0 18 12 0 0 0.00 0
全部合并:
alldat <- do.call(rbind, c(lists, list(stringsAsFactors = FALSE)))
head(alldat)
# cntry V1 V2 V3 V4 V5 V6 V7 V8 V9
# 1.1 AFGHANISTAN 1949 4 0 0 4 . 0 . 0
# 1.2 AFGHANISTAN 1950 23 0 18 6 0 0 0.00 0
# 1.3 AFGHANISTAN 1951 25 0 18 7 0 0 0.00 0
# 1.4 AFGHANISTAN 1952 25 0 17 9 0 0 0.00 0
# 1.5 AFGHANISTAN 1953 29 0 18 10 0 0 0.00 0
# 1.6 AFGHANISTAN 1954 29 0 18 12 0 0 0.00 0
tail(alldat)
# cntry V1 V2 V3 V4 V5 V6 V7 V8 V9
# 160.93 ZIMBABWE 2009 1528 0 455 977 0 95 0.11 6
# 160.94 ZIMBABWE 2010 2121 0 481 1531 0 109 0.15 7
# 160.95 ZIMBABWE 2011 2608 0 888 1584 0 136 0.18 8
# 160.96 ZIMBABWE 2012 2125 0 1006 917 0 201 0.15 9
# 160.97 ZIMBABWE 2013 3184 0 1119 1902 0 162 0.21 9
# 160.98 ZIMBABWE 2014 3278 0 1005 2097 0 177 0.22 9
(这也可以用 dplyr::bind_rows
或 data.table::rbindlist
来完成。)
实际的列名对于 R 来说有点冗长和不标准,我会留给你想出有意义的 colnames
。