使用数组读入(扫描,读取csv)R中的大数据

时间:2015-07-16 11:43:59

标签: arrays r read.csv

任何人都可以帮我了解如何在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

4 个答案:

答案 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

不是一个特别优雅的解决方案,但它具有在每个日期内索引行号的优势。