任何人都可以帮我了解如何在R中读取一个巨大的数据框(33行,38列,并且每隔39个列始终是一个标题,从#1955-2015开始每日天气开始) 我在.txt文件中有以下数据,命名为test2.txt:
# 1950-01-01 00:59:00
1 5 5 5 9
2 3 4 5 2
# 1950-01-02 00:59:00
4 5 4 4 3
9 4 3 3 3
# 1950-01-03 00:59:00
4 2 3 3 3
2 2 2 3 9
我试图把它读入R,创建一个数组或一个合理的矩阵来进行计算。我尝试使用read.csv和扫描,但我想我完全走错了路。有谁知道使用哪个命令。
read.csv("test2.txt", header=FALSE, sep="")
此外,我想在之后为列和行添加名称,但这也可以在第二步中发生。名称应该是行:A,B和列C,D,E,F,G,所以最后,数组看起来像这样,我假设的名称(例如#1950-01-03 00:59 :00)可能会丢失。
, , 1
1 5 5 5 9
2 3 4 5 2
, , 2
4 5 4 4 3
9 4 3 3 3
, , 3
4 2 3 3 3
2 2 2 3 9
答案 0 :(得分:2)
<强>被修改强>
我提供两种独立的单行解决方案。
将文件视为固定宽度格式
read.fwf("test2.txt",
widths = list(21, c(1, rep(2, 4)), rep(2, 5)),
comment.char = "")
我说明了:
file <- "# 1950-01-01 00:59:00
1 5 5 5 9
2 3 4 5 2
# 1950-01-02 00:59:00
4 5 4 4 3
9 4 3 3 3
# 1950-01-03 00:59:00
4 2 3 3 3
2 2 2 3 9"
read.fwf(textConnection(file),
widths = list(21, c(1, rep(2, 4)), rep(2, 5)),
comment.char = "")
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11
1 # 1950-01-01 00:59:00 1 5 5 5 9 2 3 4 5 2
2 # 1950-01-02 00:59:00 4 5 4 4 3 9 4 3 3 3
3 # 1950-01-03 00:59:00 4 2 3 3 3 2 2 2 3 9
将文件视为空白分隔表
您只需要一行R代码即可:
read.table("test2.txt", comment.char = "#", header = FALSE)
这样做的原因是comment.char
允许您指定要忽略的文本。在您的情况下,由于您的行以#
开头,read.table()
函数会忽略整行。
我说明了:
file <- "# 1950-01-01 00:59:00
1 5 5 5 9
2 3 4 5 2
# 1950-01-02 00:59:00
4 5 4 4 3
9 4 3 3 3
# 1950-01-03 00:59:00
4 2 3 3 3
2 2 2 3 9"
read.table(text = file, comment.char = "#", header = FALSE)
V1 V2 V3 V4 V5
1 1 5 5 5 9
2 2 3 4 5 2
3 4 5 4 4 3
4 9 4 3 3 3
5 4 2 3 3 3
6 2 2 2 3 9
答案 1 :(得分:1)
对于示例文本,我使用了以下代码:
library(stringi)
nrrep <- 3 # or 39 in your case
ncols <- 5
list.files()
dump <- readLines("test2.txt")
namelines <- str_trim(dump[(1+nrrep*(0:((length(dump))/nrrep -1 )))])
goodlines <- str_trim(dump[-(1+nrrep*(0:((length(dump))/nrrep -1 )))])
mymat <- matrix(unlist(str_split(goodlines, " ")), ncol=ncols)
rownames(mymat) <- rep(namelines, each=nrrep-1)
colnames(mymat) <- paste0("Col",LETTERS[1:ncols])
mymat
ColA ColB ColC ColD ColE
# 1950-01-01 00:59:00 "1" "3" "4" "3" "3"
# 1950-01-01 00:59:00 "5" "4" "4" "3" "2"
# 1950-01-02 00:59:00 "5" "5" "3" "4" "2"
# 1950-01-02 00:59:00 "5" "2" "9" "2" "2"
# 1950-01-03 00:59:00 "9" "4" "4" "3" "3"
# 1950-01-03 00:59:00 "2" "5" "3" "3" "9"
答案 2 :(得分:0)
我不确定您认为最终想要在R中使用的格式是否可以帮助您分析数据。在不了解更多有关读数的情况下,这里有一种方法可以使用基数R,然后如何使用tidyr
将结果数据框从宽到长重新格式化:
readings_raw <- readLines(textConnection("# 1950-01-01 00:59:00
1 5 5 5 9
2 3 4 5 2
# 1950-01-02 00:59:00
4 5 4 4 3
9 4 3 3 3
# 1950-01-03 00:59:00
4 2 3 3 3
2 2 2 3 9"))
readings_wide <- do.call(rbind, lapply(seq(1, length(readings_raw), 3), function(i) {
tmp <- read.table(text=paste(readings_raw[(i+1):(i+2)], collapse=""),
col.names=LETTERS[1:10])
tmp$date <- as.POSIXct(gsub("^# |\ *$", "", readings_raw[i]))
tmp
}))
readings_wide
## A B C D E F G H I J date
## 1 1 5 5 5 9 2 3 4 5 2 1950-01-01 00:59:00
## 2 4 5 4 4 3 9 4 3 3 3 1950-01-02 00:59:00
## 3 4 2 3 3 3 2 2 2 3 9 1950-01-03 00:59:00
tidyr::gather(readings_wide, reading, value, -date)
## date reading value
## 1 1950-01-01 00:59:00 A 1
## 2 1950-01-02 00:59:00 A 4
## 3 1950-01-03 00:59:00 A 4
## 4 1950-01-01 00:59:00 B 5
## 5 1950-01-02 00:59:00 B 5
## 6 1950-01-03 00:59:00 B 2
## 7 1950-01-01 00:59:00 C 5
## 8 1950-01-02 00:59:00 C 4
## 9 1950-01-03 00:59:00 C 3
## 10 1950-01-01 00:59:00 D 5
## 11 1950-01-02 00:59:00 D 4
## 12 1950-01-03 00:59:00 D 3
## 13 1950-01-01 00:59:00 E 9
## 14 1950-01-02 00:59:00 E 3
## 15 1950-01-03 00:59:00 E 3
## 16 1950-01-01 00:59:00 F 2
## 17 1950-01-02 00:59:00 F 9
## 18 1950-01-03 00:59:00 F 2
## 19 1950-01-01 00:59:00 G 3
## 20 1950-01-02 00:59:00 G 4
## 21 1950-01-03 00:59:00 G 2
## 22 1950-01-01 00:59:00 H 4
## 23 1950-01-02 00:59:00 H 3
## 24 1950-01-03 00:59:00 H 2
## 25 1950-01-01 00:59:00 I 5
## 26 1950-01-02 00:59:00 I 3
## 27 1950-01-03 00:59:00 I 3
## 28 1950-01-01 00:59:00 J 2
## 29 1950-01-02 00:59:00 J 3
## 30 1950-01-03 00:59:00 J 9
答案 3 :(得分:0)
file <- "# 1950-01-01 00:59:00
1 5 5 5 9
2 3 4 5 2
# 1950-01-02 00:59:00
4 5 4 4 3
9 4 3 3 3
# 1950-01-03 00:59:00
4 2 3 3 3
2 2 2 3 9"
library(dplyr)
library(stringr)
Imported <- data.frame(raw= readLines(textConnection(file))) %>%
mutate(index = cumsum(grepl("#", raw)))
Dates <- filter(Imported, grepl("#", raw))
ColumnsData <- filter(Imported, !grepl("#", raw)) %>%
group_by(index) %>%
mutate(sub_index = 1:n())
Columns <-
do.call("rbind",
lapply(1:nrow(ColumnsData),
function(i){
cols <- unlist(str_split(ColumnsData$raw[i], ""))
cols <- cols[cols != " "]
as.numeric(cols)
}
))
Columns <- cbind(ColumnsData, as.data.frame(Columns))
Columns <- merge(Dates, Columns,
by = "index")
> Columns
index raw.x raw.y sub_index V1 V2 V3 V4 V5
1 1 # 1950-01-01 00:59:00 1 5 5 5 9 1 1 5 5 5 9
2 1 # 1950-01-01 00:59:00 2 3 4 5 2 2 2 3 4 5 2
3 2 # 1950-01-02 00:59:00 4 5 4 4 3 1 4 5 4 4 3
4 2 # 1950-01-02 00:59:00 9 4 3 3 3 2 9 4 3 3 3
5 3 # 1950-01-03 00:59:00 4 2 3 3 3 1 4 2 3 3 3
6 3 # 1950-01-03 00:59:00 2 2 2 3 9 2 2 2 2 3 9
不是一个特别优雅的解决方案,但它具有在每个日期内索引行号的优势。