如何修改R程序以减少for循环的使用?

时间:2016-10-14 18:50:13

标签: r lapply

我在以下地址做作业第2部分:

https://www.coursera.org/learn/r-programming/supplement/amLgW/programming-assignment-1-instructions-air-pollution

问题: 该zip文件包含332个逗号分隔值(CSV)文件,其中包含美国332个地点的细颗粒物(PM)空气污染的污染监测数据。每个文件包含来自单个监视器的数据,每个监视器的ID号包含在文件名中。例如,监视器200的数据包含在文件" 200.csv"中。每个文件包含三个变量:

日期:以YYYY-MM-DD格式观察的日期(年 - 月 - 日) 硫酸盐:当天空气中硫酸盐PM的含量(以每立方米微克数计) 硝酸盐:该日期空气中硝酸盐PM的含量(以每立方米的微克数计) 对于此编程分配,您需要解压缩此文件并创建目录' specdata'。解压缩zip文件后,请勿对"标准数据库中的文件进行任何修改。目录。在每个文件中,您会注意到有很多天缺少硫酸盐或硝酸盐(或两者)(编码为NA)。这在美国的空气污染监测数据中很常见。

第2部分

编写一个函数,该函数读取一个充满文件的目录,并报告每个数据文件中完全观察到的案例的数量。该函数应返回一个数据框,其中第一列是文件的名称,第二列是完整案例的数量。

我的代码如下:

complete <- function(directory="d:/dev/r/documents/specdata", id)   {
df <- data.frame(no=integer(), nobs=integer())
for (i in id)   {
    sum=0
    myfilename = paste(directory,"/",formatC(i, width=3, flag="0"),".csv",
                       sep="") 
    masterfile = read.table(myfilename, header=TRUE, sep=",")
    for (j in 1:nrow(masterfile)){
        if (!is.na(masterfile[j, 2]) && !is.na(masterfile[j, 3])){
            sum = sum + 1
        }
    }
    df[i,]<-c(i, sum)
}
df
}

请注意,我将所有001.csv,002.csv,...放在目录d:/ dev / r / documents / specdata中,这就是为什么我在参数中将此字符串作为默认值。你可以看到我使用嵌套for循环来使这个工作,我意识到我应该能够用lapply替换至少一个for循环。但是由于我对C ++非常熟悉,所以我在努力解决这个问题,所以我真的不知道如何实现lapply。我在Stackoverflow上阅读了一些代码并且我理解了大部分代码,但是当我编写自己的代码时,我无法使其工作。

提前致谢!与此同时,我将再试一次。

2 个答案:

答案 0 :(得分:1)

你可以先用这样的东西来替换内循环:

rows_to_sum <- !is.na(masterfile[, 2]) & !is.na(masterfile[, 3])
df[i,] <- sum(masterfile[rows_to_sum, 1])

答案 1 :(得分:1)

此作业通过使用短语&#34;完整案例&#34;提供了一个提示。多次。你应该看看R函数complete.cases()。它将取代你的内部for循环的需要。

对于每个文件,运行complete.cases(file)。计算TRUE的数量    返回的向量中的元素。输出文件的名称和    以上计数。