我正在尝试创建一个循环,读取多个CSV文件,这些文件都具有相同类型的气温数据。但是,我想在数据上方跳过行。这些是"警报"在数据集中。每个文件可能具有不同数量的警报,因此要跳过不同的行数。见下文:
-------------First CSV file---------------
Logger 001
Alarm 1
Alarm 2
Alarm 3
Alarm 4
Date, Temp
01/01/2011, -1.2
01/02/2011, -1.3
01/03/2011, -1.1
01/04/2011, -1.2
-------------Second CSV file---------------
Logger 001
Alarm 1
Alarm 2
Alarm 3
Alarm 4
Alarm 5
Alarm 6
Alarm 7
Date, Temp
01/01/2011, -1.2
01/02/2011, -1.3
01/03/2011, -1.1
01/04/2011, -1.2
如何获取Date
,Temp
的索引告诉read.csv
跳到该行?
for (i in 1:length(csv.list)) {
df = read.csv(csv.list[i], header = T, skip=????????)
}
答案 0 :(得分:2)
您可以在循环中的read.table
之前添加几行
使用readLines
读取数据
r <- readLines(textConnection("Logger 001
Alarm 1
Alarm 2
Alarm 3
Alarm 4
Date, Temp
01/01/2011, -1.2
01/02/2011, -1.3
01/03/2011, -1.1
01/04/2011, -1.2"))
[但没有textConnection,即r <- readLines("yourcsv")
]
使用grep
dt <- grep("Date",r)
读入您的数据 - 跳过标题之前的行
read.table(text=r , header=TRUE, sep="," , skip = dt-1)
因此,要读入多个csv文件 - 这些文件将存储在数据列表中,帧
df.lst <- lapply(csv.list , function(i) {
r <- readLines(i)
dt <- grep("Date",r)
read.table(text=r , header=TRUE, sep="," , skip = dt-1)
})
答案 1 :(得分:2)
fread
可能对您有用,因为它非常适合自动检测“垃圾”标题行。这是一个例子:
首先,创建两个示例csv文件
cat("Logger 001
Alarm 1
Alarm 2
Alarm 3
Alarm 4
Date, Temp
01/01/2011, -1.2
01/02/2011, -1.3
01/03/2011, -1.1
01/04/2011, -1.2
", file = "socsv1.csv", sep = "\n")
cat("Logger 001
Alarm 1
Alarm 2
Alarm 3
Alarm 4
Alarm 5
Alarm 6
Alarm 7
Date, Temp
01/01/2011, -1.2
01/02/2011, -1.3
01/03/2011, -1.1
01/04/2011, -1.2", file = "socsv2.csv", sep = "\n")
## Check that they were created
list.files(pattern = "socsv")
# [1] "socsv1.csv" "socsv2.csv"
现在,只需使用fread
并指定sep
,而不是让fread
猜测。
library(data.table)
lapply(list.files(pattern = "socsv"), fread, sep = ",")
# [[1]]
# Date Temp
# 1: 01/01/2011 -1.2
# 2: 01/02/2011 -1.3
# 3: 01/03/2011 -1.1
# 4: 01/04/2011 -1.2
#
# [[2]]
# Date Temp
# 1: 01/01/2011 -1.2
# 2: 01/02/2011 -1.3
# 3: 01/03/2011 -1.1
# 4: 01/04/2011 -1.2
答案 2 :(得分:1)
count.fields
可以识别每个文件的第一行,其中包含两个以逗号分隔的字段。然后,您可以使用它来指定skip
。例如:
writeLines('Logger 001
Alarm 1
Alarm 2
Alarm 3
Alarm 4
Date, Temp
01/01/2011, -1.2
01/02/2011, -1.3
01/03/2011, -1.1
01/04/2011, -1.2', f <- tempfile())
writeLines('Logger 001
Alarm 1
Alarm 2
Alarm 3
Alarm 4
Alarm 5
Alarm 6
Alarm 7
Date, Temp
01/01/2011, -1.2
01/02/2011, -1.3
01/03/2011, -1.1
01/04/2011, -1.2', f2 <- tempfile())
for (x in c(f, f2)) {
ind <- match(2, count.fields(x, ','))
df <- read.csv(x, header = T, skip=ind - 1)
print(df)
}
# Date Temp
# 1 01/01/2011 -1.2
# 2 01/02/2011 -1.3
# 3 01/03/2011 -1.1
# 4 01/04/2011 -1.2
# Date Temp
# 1 01/01/2011 -1.2
# 2 01/02/2011 -1.3
# 3 01/03/2011 -1.1
# 4 01/04/2011 -1.2
答案 3 :(得分:0)
我认为有一种更简单的方法,就是通过一些选项来读取文件。
df = read.csv('weather-logger2.csv', colClasses = c('character', 'numeric'),
col.names = c('Date', 'Temp'),
na.strings = 'Temp', fill = TRUE, stringsAsFactors = FALSE)
前几行包含不是日期的字符串,当你将它们转换为日期时会给出NA(你无论如何都必须转换这种方式进行进一步处理),然后你只需要去掉缺失的值:
Date Temp
1 Alarm 1 NA
2 Alarm 2 NA
3 Alarm 3 NA
4 Alarm 4 NA
5 Alarm 5 NA
6 Alarm 6 NA
7 Alarm 7 NA
8 Date NA
9 01/01/2011 -1.2
10 01/02/2011 -1.3
11 01/03/2011 -1.1
12 01/04/2011 -1.2
df$Date = as.Date(df$Date, '%d/%m/%Y')
df = subset(df, !is.na(Date))
得到:
Date Temp
9 2011-01-01 -1.2
10 2011-02-01 -1.3
11 2011-03-01 -1.1
12 2011-04-01 -1.2