[英]dplyr::summarise() in an R function fails with “argument not numeric or logical” error
我對 R 比較陌生,我正在嘗試編寫我的第一個多步驟 function。 本質上,我想創建一個 function,它采用一個目錄並在該目錄中搜索以找到某個列(在本例中為污染物)。 然后找到該列的平均值並刪除 NA。 這是我到目前為止所擁有的:
pollutantmean <- function(directory , pollutant , min_id = 1, max_id = 332) {
setwd(directory)
dirdata <- list.files(path=getwd() , pattern='*.csv' , full.names = TRUE) %>% lapply(read_csv) %>% bind_rows
specdata <- dirdata %>% filter(between(ID,min_id,max_id))
polspecdata <- specdata %>% select(pollutant)
polspecdatamean <- polspecdata %>% summarize(mean_pollutant=mean(pollutant,na.rm=TRUE))
}
我覺得我很接近,但結果是一個錯誤:警告消息:在mean.default(污染,na.rm = TRUE):參數不是數字或邏輯:返回NA。 我相信該錯誤是由於 class 列是 col_double 造成的。 這可能是由於 dirdata 是從多個 csv 文件創建的。 任何幫助將不勝感激。 謝謝!
這是數據: zipfile_data
原始帖子中的代碼失敗,因為它在dplyr
中使用 dplyr,但不使用dplyr
引用函數。 當我們通過 RStudio 調試器運行代碼並在第 7 行停止時,我們看到以下內容:
dplyr
預期在mean(pollutant, na.rm = TRUE)
內呈現 function 參數,因此第 9 行失敗。 mean()
function 失敗,因為pollutant
參數呈現為文本字符串,而不是polspecdata
數據框中的列。
修復錯誤的一種方法是調整第 9 行,以顯式引用從先前的 function 通過%>%
pipe 運算符傳遞的數據幀,使用提取運算符的[[
形式來使用參數的字符串版本。
polspecdatamean <- polspecdata %>% summarize(mean_pollutant=mean(.data[[pollutant]],na.rm=TRUE))
最后,由於 function 應該將平均值返回給父環境,因此我們在 function 的末尾添加了在第 9 行創建的 object 的打印。
polspecdatamean
由於這是針對 Coursera 上的約翰霍普金斯大學R 編程課程的編程作業,因此我不會發布完整的答案,因為這違反了 Coursera 榮譽准則。
在第 5 行過濾數據后,function 可以簡單地返回平均值,如下所示。
mean(specdata[[pollutant]],na.rm=TRUE)
對於這個特定的作業,由於dplyr
使用非標准評估和dplyr
甚至在 JHU 課程的第三個課程序列中都沒有涵蓋,因此使用dplyr
使作業比所需的難度更大。
該代碼還有其他一些細微的缺陷,我們將把它們的更正留給讀者作為練習。 例如,給定分配要求,function 應該能夠處理以下輸入:
pollutantmean("specdata","sulfate",23) # calc mean for sensor 23
pollutantmean("specdata","nitrate",70:72) # calc mean for sensors 70 - 72
pollutantmean("specdata","sulfate",c(3,5,7,9)) # calc mean for sensors 3, 5, 7, and 9
假設您將pollutant
變量作為字符串傳遞,請嘗試使用以下 function。
library(tidyverse)
pollutantmean <- function(directory , pollutant , min_id = 1, max_id = 332) {
dirdata <- list.files(path=directory, pattern='*.csv' , full.names = TRUE) %>%
map_df(read_csv)
dirdata %>%
filter(between(ID,min_id,max_id)) %>%
summarise(mean_pollutant= mean(!!sym(pollutant),na.rm=TRUE))
}
所以你可以稱它為
pollutantmean('/path', 'sulfate', 1, 10)
使用!!sym
我們將sulfate
評估為列而不是字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.