我是 R 新手,正在练习编写 R 函数。我有 100 个单独的简历 数据文件存储在我的目录中,每个文件都用它的 id 标记,例如“1”到“100”。 我喜欢编写一个函数,将一些选定的文件读入 R,计算 每个数据文件中完整案例的数量,并将结果排列到数据框中。 下面是我写的函数。首先我读取“dat”中的所有文件。然后,使用 rbind 函数,我将所需的选定文件读入 data.frame 中。最后我计算了 使用 sum(complete.cases()) 计算完整案例的数量。这看起来很简单,但是 该功能不起作用。我怀疑索引有问题,但是 还没弄清楚为什么。搜索了各种主题,但找不到有用的 回答。非常感谢!
`complete = function(directory,id) {
dat = list.files(directory, full.name=T)
dat.em = data.frame()
for (i in id) {
dat.ful= rbind(dat.em, read.csv(dat[i]))
obs = numeric()
obs[i] = sum(complete.cases(dat.ful[dat.ful$ID == i,]))
}
data.frame(ID = id, count = obs)
}
complete("envi",c(1,3,5)) `
收到错误和警告消息: data.frame(ID = id, count = obs) 中的错误:参数暗示不同的行数:3, 5
最佳答案
您的代码存在一个问题,即每次执行循环时都会将 obs
重置为 numeric()
,因此 obs
最终会出现只有一个值(dat
中最后一个文件中的完整案例数)。
另一个问题是 dat.ful = rbind(dat.em, read.csv(dat[i]))
行将 dat.ful
重置为仅包含在该循环迭代中读取的数据帧。这不会导致错误,但您实际上不需要存储以前的数据帧,因为您只是检查读入的每个数据帧的完整案例数。
这是使用lapply
而不是循环的不同方法。请注意,该函数没有为函数提供索引向量,而是采用文件名向量。在您的示例中,您使用索引而不是文件名作为文件“id”。最好直接使用文件名,因为即使文件名是数字,如果由于某种原因文件名向量未按升序数字顺序排序,或者如果文件名不要使用连续的数字。
# Read files and return data frame with the number of complete cases in each csv file
complete = function(directory, files) {
# Read each csv file in turn and store its name and number of complete cases
# in a list
obs.list = lapply(files, function(x) {
dat = read.csv(paste0(directory,"/", x))
data.frame(fileName=x, count=sum(complete.cases(dat)))
})
# Return a data frame with the number of complete cases for each file
return(do.call(rbind, obs.list))
}
然后,要运行该函数,您需要为其提供一个目录和文件名列表。例如,要读取当前工作目录中的所有csv文件,可以这样做:
filesToRead = list.files(pattern=".csv")
complete(getwd(), filesToRead)
关于R for循环索引问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27053262/