我有一个函数定义一个目录和一个要加载和分析的文件。
函数正在读取这些值,但是当read.csv
调用时,它似乎无法识别文件名。我认为格式存在问题,但我不知道。除了永远不会创建Selectdata
dt Selectdata<-read.csv(z, header=TRUE)
之外,其他所有东西似乎都在做它应该做的事情。 z
是包含要加载的文件名的向量。
调试时,这是生成的错误:
Error in read.table(file = file, header = header, sep = sep, quote = quote, :
'file' must be a character string or connection
由于错误表示正在读取的值不是字符,字符串或连接,我厌倦了设置它as.character
等但无济于事。它必须是我想念的更简单的东西。
运行时:
Warning message:
In mean.default(Selectdata$polutant, na.rm = TRUE) :
argument is not numeric or logical: returning NA
但是,实际上,永远不会创建Selectdata
(因此,尝试表示意思,但显然没有价值)
testfun <- function(directory, polutant, id) {
setwd(directory)
x <- polutant # not needed just checking to see if polutant has been read
print(x) # not needed just checking
y <- list.files(directory, full.names=TRUE)
print(y[id]) # not needed just checking
z <- y[id]
if (length(id == 1)) {
Selectdata <- read.csv(z, header = TRUE)
}
mean(Selectdata$polutant, na.rm=TRUE)
}
答案 0 :(得分:2)
您的代码中存在多个错误,不一定与您的错误消息有关。不过,让我们轮流看看它们,结果可能会明显错误在哪里:
x <- polutant # not needed just checking to see if polutant has been read
print(x) # not needed just checking
不是错误,但不需要将polutant
分配给另一个变量。只需直接print
。
y <- list.files(directory, full.names=TRUE)
您指定directory
作为目录,但您已chdir
进入directory
。所以现在你正在寻找directory/directory
。因此,您可能找不到您的文件。
由于chdir
在函数外部具有副作用,因此无论如何使用它都不是一个好主意。删除它。
print(y[id]) # not needed just checking
这是什么印刷品?可能NULL
- 导致错误消息。
if (length(id == 1)) {
首先您将id
与1
,然后进行比较,检查其长度是否不等于0(if (some_number)
是if (some_number != 0)
)的草率捷径。你想写的是if (length(id) == 1)
。
mean(Selectdata$polutant, na.rm=TRUE)
这里有两个错误。首先,您无法在其定义的范围之外(即SelectData
内)访问if
。其次,这将尝试访问名为polutant
的数据框中的列。您可能想要的是访问具有在变量polutant
中存储的名称的列。您无法使用$
语法,您需要使用Selectdata[[polutant]]
或Selectdata[, polutant]
。
让我们留下:
testfun <- function(directory, polutant, id) {
filenames <- list.files(directory, full.names = TRUE)
if (length(id) == 1) {
filename <- filenames[id]
selectdata <- read.csv(filename, header = TRUE)
mean(selectdata[, polutant], na.rm = TRUE)
}
}
(我冒昧地统一变量命名和格式约定,并使用更多描述性变量名称。)
另外,请注意list.files
以未指定的方式返回文件名,并且可能会更改顺序,因此您无法有意义地使用固定的id
来加载给定文件。
答案 1 :(得分:0)
z
似乎不太可能是除了基于您提供的代码的文件名的字符向量之外的任何内容。你确定这完全是你跑的那个,那是你得到的确切错误吗?
仅在if
语句内创建的对象在该块存在后消失。例如
> if(1==2) {
+ a<-"ok"
+ }
> a;
Error: object 'a' not found
为什么不将mean(Selectdata$polutant, na.rm=TRUE)
放在if
语句中呢?
答案 2 :(得分:0)
我昨天正在进行实验,想出了一个我觉得很有效的方法。它使用dir
而不是将路径粘贴到文件paste
和list.files
。由于我从未见过dir
我自己也没有使用它,我无法告诉你它的性能是否优于将文件名粘贴在一起,但它似乎适用于这个例子。
结果是计算的列的列表,平均值和列的平均值。我这样做是为了显示函数中计算的内容。可以很容易地将其更改为仅输出所有列的平均值。
功能:
multifile.means <- function(directory = getwd(), pollutant, id = NULL)
{
d <- match.arg(directory, list.files())
cn <- match.arg(pollutant, c('sulfate', 'nitrate'))
## list the full file paths in the given 'directory'
p <- dir(d, full.names = TRUE)
## subset 'p' based on 'id' values
if(!is.null(id)){ id <- id[!id > length(p)]; p <- p[id] }
## read, store, and name the relevant columns
cl <- sapply(p, function(x){ read.csv(x)[,cn] }, USE.NAMES = FALSE)
colnames(cl) <- basename(p)
## return a named list of results
list(values = cl,
mean = mean(cl, na.rm = TRUE),
colMeans = colMeans(cl, na.rm = TRUE))
}
结果(默认为ID = NULL
,意味着计算目录中的所有文件):
> multifile.means('testDir', 'sulfate')
$values
001.csv 057.csv 146.csv 213.csv
[1,] 2 2 5 1
[2,] 9 4 4 4
[3,] 6 9 5 7
[4,] 10 2 5 4
[5,] 9 9 NA NA
[6,] 10 6 2 5
[7,] 4 4 2 NA
[8,] 5 4 7 4
[9,] 3 9 1 8
[10,] 4 2 1 2
$mean
[1] 4.864865
$colMeans
001.csv 057.csv 146.csv 213.csv
6.200000 5.100000 3.555556 4.375000