我必须编写一个函数来读取一个充满文件的目录,并报告每个数据文件中完全观察到的案例的数量(每个可观察实例中没有NA值)。该函数应返回一个数据框,其中第一列是文件的名称,第二列是数字 完整的案例。 请参阅下面的草稿,希望评论有所帮助!
complete <- function (directory, id = 1:332){
nobs = numeric() #currently blank
# nobs is the number of complete cases in each file
data = data.frame() #currently blank dataframe
for (i in id){
#get the right filepath
newread = read.csv(paste(directory,"/",formatC(i,width=3,flag="0"),".csv",sep=""))
my_na <- is.na(newread) #let my_na be the logic vector of true and false na values
nobs = sum(!my_na) #sum up all the not na values (1 is not na, 0 is na, due to inversion).
#this returns # of true values
#add on to the existing dataframe
data = c(data, i, nobs, row.names=i)
}
data # return the updated data frame for the specified id range
}
示例运行complete("specdata",1)
的输出是
[[1]]
[1] 1
[[2]]
[1] 3161
$row.names
[1] 1
我不确定为什么它不以常规数据帧格式显示。我也很确定我的数字也不正确。
我的工作假设是在每个第i个实例中,newread
将读取该文件中的所有数据,然后继续my_na
。这是错误的来源吗?或者是别的什么?请解释。谢谢!
答案 0 :(得分:2)
您应该考虑向向量添加值的其他方法。该功能目前正在覆盖整个地方。你询问id = 1时,当你向函数提供多个id时会更糟。它只会返回最后一个。这就是原因:
#Simple function that takes ids and adds 2 to them
myFun <- function(id) {
nobs = c()
for(i in id) {
nobs = 2 + i
}
return(nobs)
}
myFun(c(2,3,4))
[1] 6
我告诉它每个id返回值加2,但它只给了我最后一个。我应该这样写:
myFun2 <- function(id) {
nobs = c()
for(i in 1:length(id)) {
nobs[i] <- 2 + id[i]
}
return(nobs)
}
myFun2(c(2,3,4))
[1] 4 5 6
现在它提供了正确的输出。有什么不同?首先,nobs
对象不再被覆盖,它会被追加。请注意for循环标题中的子集括号和新计数器。
同样构建对象并不是使用R的最佳方法。它的构建是为了用更少的东西做更多的事情:
complete <- function(directory, id=1:332) {
nobs <- sapply(id, function(i) {
sum(complete.cases(read.csv(list.files(path=directory, full.names=TRUE)[i]) )) } )
data.frame(id, nobs)
}
如果您想修改代码,请尝试以下操作:
complete <- function (directory, id = 1:332){
nobs = numeric(length(id)) #currently blank
# nobs is the number of complete cases in each file
for (i in 1:length(id)) {
#get the right filepath
newread = read.csv(paste(directory,"/",formatC( id[i] ,width=3,flag="0"),".csv",sep=""))
my_na <- is.na(newread) #let my_na be the logic vector of true and false na values
nobs[i] = sum(!my_na) #sum up all the not na values (1 is not na, 0 is na, due to inversion).
#this returns # of true values
}
data.frame(id, nobs) # return the updated data frame for the specified id range
}
答案 1 :(得分:0)
由于我不知道您所指的数据,并且由于没有给出样本,我可以将其作为您的功能的编辑 -
complete <- function (directory, id = 1:332){
data = data.frame()
for (i in id){
newread = read.csv(paste(directory,"/",formatC(i,width=3,flag="0"),".csv",sep=""))
newread = newread[complete.cases(newread),]
nobs = nrow(newread)
data[nrow(data)+1,] = c(i,nobs)
}
names(data) <- c("Name","NotNA")
return(data)
}