我需要编写一个带有两个参数的函数:directory
和id
。 directory
本质上是直接使用R. id
是文件的名称。所有文件的扩展名为csv
,名称介于001到332之间。
该函数应返回包含两列的数据框:id
和nrow
。 id
是文件的名称,nrow
是该文件中的行数。
我从以下代码开始,但这仅适用于只有1 id
传递给函数的情况:
directory = 'specdata'
id = 1 # this should be able to take a list of numbers i.e. 1:332
id1 = if(nchar(id) == 1) {paste("00",id,sep="")}
else if (nchar()== 2) {paste("0",id,sep="")})
file = paste(directory,"/",as.character(id1),".csv", sep="")
data = read.csv(file)
casenum = nrow(data)
output = c(id1, casenum)
如何修改代码,以便在传递超过1 id
时函数可以重复。例如,行id = c(1,2,3,5,6)
正在通过?
我正在考虑使用lapply
或sapply
,但不知道从哪里开始。
谢谢,
答案 0 :(得分:4)
如果您只想拥有每个文件中的行数,那么我实际上建议您使用命令行工具wc
:它会更快。
wc -l *.csv
将为您提供一个ASCII表,其中包含第一列中的行数和其后的文件名
(GNU core utilities用于Windows命令行的wc
可用,例如{{3}}的一部分。)
如果要为目录中的每个 .csv文件执行某些操作,请使用
file = Sys.glob (paste0 (directory, "/*.csv")
无论如何,这是你要求更具体的内容:
directory = 'specdata'
id = 1:17
file = sprintf ("%s/%03i.csv", directory, id) # now a vector with file names
casenum = sapply (file, function (f) nrow (read.csv (f)))
cbind (id, casenum)
# or, if you prefer a data.frame
data.frame (id = id, casenum = casenum)
答案 1 :(得分:2)
虽然没有必要,但如果在命名函数中包装操作,则更容易阅读。这可以在另一个功能中:
countall <- function(directory, ids) {
countlines <- function(id) {
## Your code, copied from the question
id1 = if(nchar(id) == 1) {paste("00",id,sep="")}
else if (nchar(id)== 2) {paste("0",id,sep="")}
file = paste(directory,"/",as.character(id1),".csv", sep="")
data = read.csv(file)
casenum = nrow(data)
## No need to attach the id here, as you can use the names
return(casenum)
}
retval <- lapply(ids, countlines) # or sapply, to return a vector instead of a list
names(retval) <- ids
return(retval)
}
使用以下命令运行:
countall('specdata', 1:10)