1

我正在运行以下代码以打开一组具有温度与时间数据的 CSV 文件

temp = list.files(pattern="*.csv")
for (i in 1:length(temp)) 
{
  assign(temp[i], read.csv(temp[i], header=FALSE, skip =20))
  colnames(as.data.frame(temp[i])) <- c("Date","Unit","Temp")
}

数据框中的数据如下所示:

                   V1 V2   V3
1 6/30/13 10:00:01 AM  C 32.5
2 6/30/13 10:20:01 AM  C 32.5
3 6/30/13 10:40:01 AM  C 33.5
4 6/30/13 11:00:01 AM  C 34.5
5 6/30/13 11:20:01 AM  C 37.0
6 6/30/13 11:40:01 AM  C 35.5

我只是想分配列名,但收到以下错误消息:

Error in `colnames<-`(`*tmp*`, value = c("Date", "Unit", "Temp")) : 
  'names' attribute [3] must be the same length as the vector [1]

我认为这可能与我的循环如何读取 csv 文件有关。它们都存储在 R 中的同一目录中。

谢谢你的帮助!

4

5 回答 5

1
  1. “read.csv”返回一个data.frame,所以你不需要“as.data.frame”调用;
  2. 您可以对“read.csv”使用“col.names”参数来分配列名;
  3. 我不知道您使用的是哪个版本的 R,但是“colnames(as.data.frame(...)) <-”只是一个不正确的调用,因为它需要“as.data.frame<-”函数至少在 2.14 版中不存在。
于 2013-07-09T21:19:56.927 回答
1

以下是解决您的困境的短期方法,但您确实需要阅读更多关于使用Ras 的内容,我希望您会很快陷入另一个混乱。也许从不使用开始assign

lapply(list.files(pattern = "*.csv"), function (f) {
  df = read.csv(f, header = F, skip = 20))
  names(df) = c('Date', 'Unit', 'Temp')
  df
}) -> your_list_of_data.frames

虽然您更有可能想要这个(编辑以保留文件名信息):

df = do.call(rbind,
             lapply(list.files(pattern = "*.csv"), function(f)
                    cbind(f, read.csv(f, header = F, skip = 20))))
names(df) = c('Filename', 'Date', 'Unit', 'Temp')
于 2013-07-09T21:23:33.930 回答
1

我会采取一种稍微不同的方法,这可能更容易理解:

temp = list.files(pattern="*.csv")
for (i in 1:length(temp)) 
{
  tmp <- read.csv(temp[i], header=FALSE, skip =20)
  colnames(tmp) <- c("Date","Unit","Temp")
  # Now what do you want to do?
  # For instance, use the file name as the name of a list element containing the data?
}

更新:

temp = list.files(pattern="*.csv")
stations <- vector("list", length(temp))
for (i in 1:length(temp)) {
  tmp <- read.csv(temp[i], header=FALSE, skip =20)
  colnames(tmp) <- c("Date","Unit","Temp")
  stations[[i]] <- tmp
}
names(stations) <- temp # optional; could process file names too like using basename

station1 <- station[[1]] # etc  station1 would be a data.frame

这第二部分也可以改进,具体取决于您计划如何使用数据以及有多少数据。一个很好的命令是 str(some object)。它将真正帮助您理解 R 的数据结构。

更新#2:

将单个数据框放入您的工作区将非常困难 - 比我更聪明的人可能知道一些技巧。既然你想绘制这些,我首先让名字更像你想要的:

names(stations) <- paste(basename(temp), 1:length(stations), sep = "_")

然后我将遍历上面创建的列表,如下所示,随时创建您的图:

for (i in 1:length(stations)) {
    tmp <- stations[[i]]
    # tmp is a data frame with columns Date, Unit, Temp
    # plot your data using the plot commands you like to use, for example
    p <- qplot(x = Date, y = Temp, data = tmp, geom = "smooth", main = names(stations)[i])
    print(p)
    # this is approx code, you'll have to play with it, and watch out for Dates
    # I recommend the package lubridate if you have any troubles parsing the dates
    # qplot is in package ggplot2
}

如果要将它们保存在文件中,请使用以下命令:

pdf("filename.pdf")
# then the plotting loop just above
dev.off()

将创建一个多页 pdf。祝你好运!

于 2013-07-09T21:16:19.930 回答
1

通常不建议在 R 中使用“分配”语句。(我真的应该找到一些资源来说明为什么会这样。)

您可以使用以下函数执行您正在尝试的操作:

read.a.file <- function (f, cnames, ...) {
  my.df <- read.csv(f, ...)
  colnames(my.df) <- cnames
  ## Here you can add more preprocessing of your files.
}

并使用此循环遍历文件列表:

lapply(X=temp, FUN=read.a.file, cnames=c("Date", "Unit", "Temp"), skip=20, header=FALSE)
于 2013-07-09T21:16:57.497 回答
0

乍一看,您似乎缺少一组子括号[],围绕您的临时列表的元素。您的属性列表具有三个元素,但是因为您有temp[i]而不是temp[[i]]for 循环实际上并没有访问列表的元素,因此将其视为长度为 1 的元素,如错误所述。

于 2013-07-09T21:16:31.900 回答