2015-06-13 14 views
0

我想寫的R腳本,根據從一個數據或更多的332個監測站指定污染物(硝酸鹽或硫酸鹽)的平均平均值。每個電臺的數據保存在一個單獨的文件中,編號爲1:332。我是R新手,爲了公平對待任何選擇幫助我的人,我應該說這是一個家庭作業問題。我已經寫了下面的腳本,它適用於只有一個文件:計算在多個文件中保存的數據

pollutantmean <- function(directory, pollutant, id = 1:332) { 
    filepath <- "/Users/jim/Documents/Coursera/2_R_Prog/Data" 
    for(i in seq_along(id)) { 
      if(id < 10) { 
        name <- paste("00", id[i], sep = "") 
      } 
      if(id >= 10 && id < 100) { 
        name <- paste("0", id[i], sep = "") 
      } 
      if(id >= 100) { 
        name <- id[i] 
      }  
    } 
    file <- paste(name, "csv", sep = ".") 
    station <- paste(filepath, directory, file, sep = "/") 
    monitor <- read.csv(station) 
    if(pollutant == "nitrate") { 
      x <- mean(monitor$nitrate, na.rm = T) 
    } 
    if(pollutant == "sulfate") { 
      x <- mean(monitor$sulfate, na.rm = T) 
    } 
    x 
} 

但是,如果我輸入多個文件(如70:72)我得到的平均值爲最後的文件只(72)。這表明它正在計算每個文件的平均值,然後用下一個文件的平均值覆蓋它,以便只輸出最後一個文件的平均值。我可以使用rbind()來解決這個問題,但我無法弄清楚如何爲每個變量分配唯一的名稱,然後這些變量就會成爲rbind()的參數。我會很感激任何人可以提供的幫助。 乾杯, 吉姆

+0

http://stackoverflow.com/questions/23640594/reading-multiple-files-and-calculating-mean-based-on-user-input – user227710

+0

你不」遍歷您的文件! –

+0

謝謝你的幫助,朱利安。你給了我關於'sprintf'和使用循環的有用建議。但是,你的代碼給出了與'length(id)'相同數量的方法。我最終需要的僅僅是一個平均值,所以我需要找到某種方法將所有數據放入一個單獨的向量,然後從中計算平均值。 –

回答

0

你做了這些文件不循環。

,你會得到最後一個文件的平均,因爲當你遍歷IDS創建名字,你的循環返回創建的姓氏。

您應該創建名稱,然後站和循環在它的載體!提示:你不需要循環和條件語句來創建你的名字,你可以使用sprintf來預先確定你期望的字符串的大小(3),以及你想要「擴展」字符串的內容(0 )

> id <- c(1, 10, 100) 
> names <- sprintf("%03d", id) 
> names 
[1] "001" "010" "100" 

,這應該工作:

pollutantmean <- function(directory, pollutant, id = 1:332) { 
    filepath <- "/Users/jim/Documents/Coursera/2_R_Prog/Data" 

    names <- sprintf("%03d", id) 
    files <- paste0(names, ".csv") # Or directly : files <- sprintf("%03d.csv", id) 
    station <- file.path(filepath, directory, files) 

    means <- numeric(length(station)) 

    for (i in seq_along(station)) { 
    monitor <- read.csv(station[i]) 
    if(pollutant == "nitrate") { 
     means[i] <- mean(monitor$nitrate, na.rm = T) 
    } else if(pollutant == "sulfate") { 
     means[i] <- mean(monitor$sulfate, na.rm = T) 
    } 
    } 
    return(means) 
} 

編輯: 如果你想有一個單一的意思,你可以使用上面的代碼和ponderate由nrow非NA各手段。更換由循環:

means <- numeric(length(station)) 
counts <- numeric(length(station)) 

for (i in seq_along(station)) { 
    monitor <- read.csv(station[i]) 
    if(pollutant == "nitrate") { 
    means[i] <- mean(monitor$nitrate, na.rm = TRUE) 
    counts[i] <- sum(!is.na(monitor$nitrate)) 
    } else if(pollutant == "sulfate") { 
    means[i] <- mean(monitor$sulfate, na.rm = TRUE) 
    counts[i] <- sum(!is.na(monitor$sulfate)) 
    } 
} 

myMean <- sum(means * counts)/sum(counts) 
return(myMean) 

因爲你的第一個目的是爲了收集你的DATAS到一個載體中,這裏是創建一個列表,其中每個元素是每個datasframes的慾望「污染物」變的解決方案,不公開收集所有的矢量變成1,然後我們可以計算這個矢量的平均值。

pollutantmean <- function(directory, pollutant, id = 1:332) { 
    filepath <- "/Users/jim/Documents/Coursera/2_R_Prog/Data" 

    names <- sprintf("%03d", id) 
    files <- paste0(names, ".csv") # Or directly : files <- sprintf("%03d.csv", id) 
    station <- file.path(filepath, directory, files) 

    li <- lapply(station, function(x) { 
    monitor <- read.csv(x) 
    if(pollutant == "nitrate") { 
     monitor$nitrate 
    } else if(pollutant == "sulfate") { 
     monitor$sulfate 
    } 
    }) 

    myMean <- mean(unlist(li)) 

    return(myMean) 
} 
0

Julien Navarre的第二個污染物函數的一個小小的修正。計算平均值時,不會忽略NA值,這可能會影響整體結果。所以計算平均值的線應該是這樣的。

myMean <- mean(unlist(l), na.rm=TRUE) 
相關問題