首页 文章

R:为什么我没有得到按预期返回向量的函数?

提问于
浏览
-1
corr <- function(directory, threshold) { 
          files <- list.files(directory, full.names = TRUE)
          nu <- numeric()
          for(i in length(files)) {
            my_data <- read.csv(files[i])
            if (sum(complete.cases(my_data)) >= threshold) {
              vec_sul <- my_data[complete.cases(my_data),]$sulfate
              vec_nit <- my_data[complete.cases(my_data),]$nitrate
              nu <- c(nu, cor(vec_sul, vec_nit))
            }
          }
      nu
    }

我有一个.csv文件列表,它们位于我希望作为参数传递给上述函数的目录中 . 我也传递阈值作为第二个参数 . 目标是读取目录参数中的所有文件,并检查文件是否具有超过作为第二个arg传递的阈值的完整案例 .

那些通过这个标准的文件将被进一步检查,并在评估其中的两个变量之间的相关性:硫酸盐和硝酸盐 . 与具有比阈值更完整的情况的文件相关联的一系列这样的相关值将被连接到数值变量向量 . 在循环执行结束时,我希望函数返回包含在“if”循环中计算的一系列相关值的向量 .

cr < - corr(“specdata”,150)当我在控制台中运行上面的代码行时,我得到一个null的数字变量 . 有人可以帮我修复代码吗?

2 回答

  • 0

    虽然已经多次看到这种错误,但它仍然会发生 . 你要

    i in 1:length(files)
    

    你得到 numeric(0) (你说的是"numeric null"),因为你的循环只读取最终文件 . 我猜最终文件不满足 sum(complete.cases(my_data)) >= threshold 所以没有添加到 nu ,初始化为 numeric(0) .


    另外,我想指出一点

    vec_sul <- my_data[complete.cases(my_data),]$sulfate
    vec_nit <- my_data[complete.cases(my_data),]$nitrate
    nu <- c(nu, cor(vec_sul, vec_nit))
    

    可以替换为

    nu <- c(nu, with(my_data, cor(sulfate, nitrate, use = "complete.obs")))
    
  • 0

    考虑跨文件列表的向量化 lapply() ,这避免了扩展预设向量 . 唯一的调整是lapply将返回等于输入列表的长度 files ,因此添加 else 语句以填充具有未满足阈值条件的数据帧 . 但是在循环之外, nu 被删除了这些NA .

    corr <- function(directory, threshold) { 
    
               files <- list.files(directory, full.names = TRUE)
               nu <- lapply(files, function(i) {
                   my_data <- read.csv(i)
                   if (sum(complete.cases(my_data)) >= threshold) {
                       vec_sul <- my_data[complete.cases(my_data),]$sulfate
                       vec_nit <- my_data[complete.cases(my_data),]$nitrate
                       temp <- cor(vec_sul, vec_nit)
                   } else {
                       temp <- NA           # SET NAs   
                   }
                   return(temp)
               })
    
           nu <- nu[!is.na(nu)]             # REMOVE NAs
           return(nu)
    }
    

    或者,尝试甚至 vapply() (可以说稍快一点)来指定数字向量返回

    corr <- function(directory, threshold) { 
    
               files <- list.files(directory, full.names = TRUE)          
               nu <- vapply(files, function(i) {
                   my_data <- read.csv(i)
                   if (sum(complete.cases(my_data)) >= threshold) {
                       vec_sul <- my_data[complete.cases(my_data),]$sulfate
                       vec_nit <- my_data[complete.cases(my_data),]$nitrate
                       temp <- cor(vec_sul, vec_nit)
                   } else {
                       temp <- NA           # SET NAs    
                   }
                   return(temp)
               }, numeric(1))          
    
           nu <- nu[!is.na(nu)]             # REMOVE NAs
           return(nu)
    }
    

相关问题