dplyr::summaryise()在R函数中出现 "参数不是数字或逻辑 "错误。

问题描述 投票:0回答:1

我对R比较陌生,我正在尝试编写我的第一个多步骤函数。本质上,我想创建一个函数,接受一个目录,并在该目录中搜索,以找到某个列(在本例中,污染物)。然后找到该列的平均值,并去除NAs。这就是我目前的成果。

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))
} 

我觉得已经很接近了,但结果是错误的。Warning message:In mean.default(pollutant, na.rm = TRUE) : argument is not numeric or logical: returning NA. 我相信这个错误是由于列类是col_double。这可能是由于dirdata是由多个csv文件创建的。任何帮助都将是非常感激的。谢谢你的帮助

这是数据。zipfile_data

r function dataframe double mean
1个回答
1
投票

原帖中的代码失败了,因为它使用了 dplyr 的函数中,但不使用 dplyr 引用功能. 当我们通过 RStudio 调试器运行代码并在第 7 行停止时,我们看到以下内容。

enter image description here

dplyr 没有将函数参数呈现在 mean(pollutant, na.rm = TRUE) 正如预期的那样,所以第9行失败。该 mean() 函数失败,因为 pollutant 参数以文本字符串的形式呈现,而不是以列的形式出现在 polspecdata 数据帧。

修正错误的方法之一是调整第9行,通过以下方法显式引用前一个函数传递过来的数据帧 %>% 管道运营商,使用 [[ 的形式来使用参数的字符串版本。

polspecdatamean <- polspecdata %>% summarize(mean_pollutant=mean(.data[[pollutant]],na.rm=TRUE))

最后,由于函数应该将平均数返回到父环境,所以我们在函数的最后添加一个第9行创建的对象的打印。

polspecdatamean

由于这是约翰-霍普金斯大学的编程作业。R编程 Coursera上的课程,我不会发布完整的答案,因为这违反了Coursera荣誉守则。

简化解决方案

一旦在第5行中对数据进行了过滤,函数可以简单地返回平均值,如下所示。

mean(specdata[[pollutant]],na.rm=TRUE)

结论

在这一特定任务中,使用 dplyr 使得任务比需要的难度更大,因为事实是 dplyr 使用非标准评价和 dplyr 甚至在JHU的课程中,直到第三门课程才有涉及。

这段代码还有其他一些微妙的缺陷,我们将其纠正作为一项练习留给读者。例如,给定任务要求,函数应该能够处理以下输入。

pollutantmean("specdata","sulfate",23) # calc mean for sensor 23
pollutantmean("specdata","nitrate",70:72) # calc mean for sensors 70 - 72 

1
投票

假设你传递的是 pollutant 变量为字符串,请尝试使用下面的函数。

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 作为列而不是字符串。

© www.soinside.com 2019 - 2024. All rights reserved.