Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 从332.csv文件中提取数据,并返回文件中每个变量的观察案例数_R_Csv - Fatal编程技术网

R 从332.csv文件中提取数据,并返回文件中每个变量的观察案例数

R 从332.csv文件中提取数据,并返回文件中每个变量的观察案例数,r,csv,R,Csv,我正在编写一个R函数,它读取一个包含332.csv文件的目录,并报告每个数据文件中完全观察到的案例数。函数返回一个数据帧,其中第一列是文件名,第二列是完整案例数。例如: ID OBS 1 233 2 149 etc. 以下是我编写的代码: complete <- function(directory, id = 1:332) { files_full <- list.files(directory, full.names = TRUE) nobs <

我正在编写一个R函数,它读取一个包含332.csv文件的目录,并报告每个数据文件中完全观察到的案例数。函数返回一个数据帧,其中第一列是文件名,第二列是完整案例数。例如:

ID  OBS
1   233
2   149
etc.
以下是我编写的代码:

complete <- function(directory, id = 1:332) {
    files_full <- list.files(directory, full.names = TRUE)
    nobs <- sum(complete.cases(files_full[id]))
    data <- data.frame(id, nobs)
    return(data)
}

这里的问题是,虽然函数确实在运行,但它为我的列中的每个nob提供了一个值1。

sumplete.casesfiles\u full[i]没有多大意义,这可能是您出错的地方

我会这样做

1-定义一个函数来处理单个数据集

read_and_summarise <- function(f, ...) {d <- read.csv(f, ...) ; sum(complete.cases(d))}
2-将此功能应用于所有文件

lf <- list.files(directory, full.names = TRUE)
vapply(lf, read_and_summarise, 0L)

未经测试的

有点不同的方法:

complete <- function(directory, pattern = "csv$") {
    setNames(as.data.frame(do.call(
            rbind,
            lapply(
                list.files(directory, pattern = pattern, full.names=TRUE),
                function(fname) list(fname, sum(complete.cases(read.csv(fname))))
            )
   )), c("file", "complete"))
}

让我们看一下您的代码实际在做什么:

complete <- function(directory, id = 1:332) {
    # list files
    files_full <- list.files(directory, full.names = TRUE)
    # create an empty placeholder, to grow sequentially. Known in some circles as R Inferno 
    # http://www.burns-stat.com/documents/books/the-r-inferno/
    dat <- data.frame()
    for (i in id) { # select filenames based on their position in the list 
                    # (prone to errors, because it depends on the order)
            dat <- rbind(dat, read.csv(files_full[i])) # read the data, and append it 
                                                       # to previous data.frame. Why??
            nobs <- sum(complete.cases(files_full[i])) # number of complete cases...
                                                       # in a character vector of length 1
            data <- data.frame(id, nobs)               # this gets overwritten every time
    }
    data
}
以下是您可能想写的内容:

complete <- function(directory, id = 1:332) {
    # list files
    files_full <- list.files(directory, full.names = TRUE)
    files_toread <- files_full[id] # filter out unwanted files (tip: ?grep is better)
    output <- data.frame(id = id, nobs = 0)
    for (i in id) { 
            tmp <- read.csv(files_toread[i]) # read the data
            nobs <- sum(complete.cases(tmp)) # number of complete cases
            output[i, "nobs"] <- nobs
    }
    output
}
编辑:
此代码将id与文件名匹配,而不是按编号id对所有文件进行子集设置。将创建一个嵌套函数来读取和分析文件。在data.frame中,新函数列表应用于匹配文件路径的向量,在一个非列表中,仅返回完整案例的数量。

这是我的解决方案,看起来更容易阅读:

complete <- function(directory,id=1:332){
    filenames <- sprintf("%03d.csv", id)
    filePaths <- paste(directory, filenames, sep="/")
    nFiles=length(id)
    output <- matrix(ncol=2, nrow=nFiles)
    for(i in 1:nFiles){
        output[i,]= c(id[i],sum(complete.cases(read.csv(filePaths[i]))))
    }
    output <- setNames(data.frame(output),c("id","nobs"))
    output
}

希望这对某人有所帮助。

我认为这更简单,更容易理解:

    complete <- function(dir, id = 1:332){

    dir <- list.files(dir, full.names = T)
    count <- data.frame()

    for(i in id){
            ok <- sum(complete.cases(read.csv(dir[i])))
            count <- rbind(count, ok)
    }
    count_table <- cbind(id, count)
    colnames(count_table) <- c("id", "nobs")
    count_table
    }

在保持初始functiondirectory,id=1:332不变的情况下,有没有办法做到这一点?我想知道是否有人会建议使用lf%>%read.csv%>%complete.cases%>%sum%>%setNamesalternative@Daniel现在还不完全清楚使用id=1:332时的真正目的是什么?只选择前332个文件?但是如果您意外地在列表中有其他文件,该怎么办?在list.files之后对特定的文件名进行grep不是更好吗?@baptiste谢谢你的帮助,我真的很感激。我已经更新了代码,将dat[ID]编辑为刚才的ID。fx似乎工作正常一半:它在一个整洁的小列表中打印每个csv文件的正确ID,但它没有显示每个文件的非NA观察的正确数量。我应该如何编辑我的代码来修复此问题?@zero323非常感谢!这个函数可以工作,但我想知道是否有办法不在数据框中显示文件和文件名?我想展示一个更简单的列表。非常感谢@baptiste!是的,我确实知道我不需要重新查找文件。删除后,我在OP中更新了以下代码。您将如何修改此代码以获得所需的结果?我不完全清楚你所说的文件是什么意思?完整是长度为1的字符向量,我如何更改它以查找每个单独的CSV并提取该文件中每个列的完整案例?请以更详细的方式描述你的解决方案。1。在目录中创建文件列表。2.创建文件编号列表并将其格式设置为数字。3.从ID参数与数字列表匹配的文件列表中选择文件。4.为选定文件创建文件路径。5.创建函数以对所选文件中的完整记录求和。5.创建id为column1和column2的数据帧,作为应用于选定文件的上一个求和函数的结果。
complete <- function(directory,id=1:332){
    filenames <- sprintf("%03d.csv", id)
    filePaths <- paste(directory, filenames, sep="/")
    nFiles=length(id)
    output <- matrix(ncol=2, nrow=nFiles)
    for(i in 1:nFiles){
        output[i,]= c(id[i],sum(complete.cases(read.csv(filePaths[i]))))
    }
    output <- setNames(data.frame(output),c("id","nobs"))
    output
}
    complete <- function(dir, id = 1:332){

    dir <- list.files(dir, full.names = T)
    count <- data.frame()

    for(i in id){
            ok <- sum(complete.cases(read.csv(dir[i])))
            count <- rbind(count, ok)
    }
    count_table <- cbind(id, count)
    colnames(count_table) <- c("id", "nobs")
    count_table
    }