问题描述
我是R的新手。 我为作业编写了代码,该作业读取了多个csv文件并将其绑定到数据帧中,然后根据id来计算硝酸盐或硫酸盐的平均值。
数据样本:
Date sulfate nitrate ID
<date> <dbl> <dbl> <dbl>
1 2003-10-06 7.21 0.651 1
2 2003-10-12 5.99 0.428 1
3 2003-10-18 4.68 1.04 1
4 2003-10-24 3.47 0.363 1
5 2003-10-30 2.42 0.507 1
6 2003-11-11 1.43 0.474 1
...
要读取文件并创建data.frame,我编写了此函数:
pollutantmean <- function (pollutant,id = 1:332) {
#creating a data frame from several files
file_m <- list.files(path = "specdata",pattern = "*.csv",full.names = TRUE)
read_file_m <- lapply(file_m,read_csv)
df_1 <- bind_rows(read_file_m)
# delete NAs
df_clean <- df_1[complete.cases(df_1),]
#select rows according to id
df_asid_clean <- filter(df_clean,ID %in% id)
#count the mean of the column
mean_result <- mean(df_asid_clean[,pollutant])
mean_result
但是,当应用read_csv函数时,硝酸盐列中的某些条目被读取为col_logical,尽管该列的整个类仍然是数字,并且条目是数字。似乎代码“期望”接收逻辑值,尽管实际值不是。 在阅读过程中,我得到以下消息:
<...>
Parsed with column specification:
cols(
Date = col_date(format = ""),sulfate = col_double(),nitrate = col_logical(),ID = col_double()
)
Warning: 41 parsing failures.
row col expected actual file
2055 nitrate 1/0/T/F/TRUE/FALSE 0.383 'specdata/288.csv'
2067 nitrate 1/0/T/F/TRUE/FALSE 0.355 'specdata/288.csv'
2073 nitrate 1/0/T/F/TRUE/FALSE 0.469 'specdata/288.csv'
2085 nitrate 1/0/T/F/TRUE/FALSE 0.144 'specdata/288.csv'
2091 nitrate 1/0/T/F/TRUE/FALSE 0.0984 'specdata/288.csv'
.... ....... .................. ...... ..................
See problems(...) for more details.
我试图通过编写更改列类
df_1[,nitrate] <- as.numeric(as.character(df_1[,nitrate])
,但在绑定行之后,但这仅表明在计算平均值的步骤中再次引入了NA。
这有什么问题,我该如何解决? 感谢您的帮助!
更新:尝试插入read_csv(col_types = list ...),但未定义“文件”参数。据我了解,R首先读取read_csv,然后然后读取,因为当时没有给出“文件”,所以显示错误。
解决方法
readr::read_csv()
解析列类型失败的问题可以通过在col_types=
中传递lapply()
自变量来解决。我们这样做如下:
pollutantmean <- function (directory,pollutant,id=1:332){
require(readr)
require(dplyr)
file_m <- list.files(path = directory,pattern = "*.csv",full.names = TRUE)[id]
read_file_m <- lapply(file_m,read_csv,col_types=list(col_date(),col_double(),col_integer()))
# rest of code goes here. Since I am a Community Mentor in the
# JHU Data Science Specialization,I am not allowed to post
# a complete solution to the programming assignment
}
请注意,我使用提取操作符的[
形式通过id
向量对文件名列表进行子集化,该向量是函数的参数,这样可以避免读取大量不完整的数据没必要。这样就无需在问题中发布的代码中使用filter()
语句。
使用一些其他编程语句来完成作业,我的答案中的代码为随作业发布的三个示例产生了正确的结果,如下所示。
> pollutantmean("specdata","sulfate",1:10)
[1] 4.064128
> pollutantmean("specdata","nitrate",70:72)
[1] 1.706047
> pollutantmean("specdata",23)
[1] 1.280833
或者,我们可以使用匿名函数来实现lapply()
,该函数还使用read_csv()
,如下所示:
read_file_m <- lapply(file_m,function(x) {read_csv(x,col_integer()))})
注意::完全可以理解,曾经接触过tidyverse
的学生想将其用于编程作业,而dplyr
不是直到序列中的下一个课程(并且完全没有涵盖readr
)之前引入t使得在 R编程中的赋值,尤其是第一个赋值,其中{ {1}}非标准评估使人们感到满意。这种情况的一个例子是dplyr
上的另一个Stackoverflow问题。