【问题标题】:R: why am I not getting the function to return the vector as intended?R:为什么我没有让函数按预期返回向量?
【发布时间】:2017-01-12 03:24:57
【问题描述】:
    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 文件列表,我希望将其作为参数传递给上述函数。我还将阈值作为第二个参数传递。目的是读取目录参数中的所有文件,并检查文件是否包含超过作为第二个参数传递的阈值的完整案例。

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

cr

【问题讨论】:

  • 两个问题。 1) 该作业的 hte RHS 上的 'nu' 可能意味着是一个 "i" 和 2) 原样,你只会看到最后一个,因为你没有使用 "nu" 的索引(并且可能是三分之一,因为最好的方法是不使用数字向量来列出这个......或者会更好。第四个问题是彭的 R 课程的学生应该使用该课程提供的网站帮助设施.

标签: r for-loop return


【解决方案1】:

虽然这种错误已经出现过很多次了,但还是会发生。你想要的

i in 1:length(files)

你得到numeric(0)(你所说的“数字空”),因为你的循环只读取最终文件。我猜最终的文件不满足sum(complete.cases(my_data)) &gt;= 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")))

【讨论】:

    【解决方案2】:

    考虑跨文件列表的矢量化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)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-08
      • 2012-09-07
      相关资源
      最近更新 更多