【问题标题】:Why is R not recognizing my object in for loop?为什么 R 不能在 for 循环中识别我的对象?
【发布时间】:2020-12-16 17:49:28
【问题描述】:

我正在尝试使用两遍方法分别筛选数据集中的不同分组变量以查找不良记录和异常值。我想分别对每个变量进行筛选。我尝试运行一个 for 循环并使用 tidyverse 语言,预期数据帧列表,但收到一条错误消息。这是一个例子:

require(tidyverse)

# make the example dataframe
factor1 <- c("yes", "no","yes","no","no", "yes")
factor2 <- c("Female","Female","Male","Male", "Male", "Female")
a <- sample(1:100, 6, replace=TRUE)
b <- sample(1:100, 6, replace=TRUE)
c <- sample(1:100, 6, replace=TRUE)
d <- sample(1:100, 6, replace=TRUE)
e <- sample(1:100, 6, replace=TRUE)
simpledata <- data.frame(factor1, factor2, a, b, c, d, e)

#list of variable names to loop over
simple_vars = c("a","b","c","d","e")
   
#initialize list to store results in     
simplelist <- vector(mode="list", length=length(simple_vars))

for(i in simple_vars){
    simplelist[[i]] <<- simpledata %>%
    group_by(factor1, factor2) %>%
    filter(.data[[i]] < 5*median(.data[[i]])) %>%
    filter(between(.data[[i]], mean(.data[[i]])-3*sd(.data[[i]]),
                mean(.data[[i]])+3*sd(.data[[i]])))
}

我收到以下错误:"Error in simplelist[[i]] &lt;&lt;- simpledata %&gt;% group_by(factor1, factor2) %&gt;% : object 'simplelist' not found"。除了我可以在我的环境窗口中看到“simplelist”!这里出了什么问题?

另外,如果有一种更优雅的方式来使用 tidyverse 表示法和 transmute_at 或其他东西(可能有)来实现我的总体目标,我会很高兴听到它,但我的问题是为什么 R 不能识别我初始化的列表。

【问题讨论】:

  • 使用simplelist[[i]] &lt;- 而不是simplelist[[i]] &lt;&lt;-。无论如何,使用&lt;&lt;- 很少是合理的,更多的是表明不正确的功能架构和范围违规。在这种情况下,它既没有意义(for 循环内的代码与for 之外的代码在完全相同的范围内),而且正如您现在所看到的,会适得其反。

标签: r for-loop initialization tidyverse


【解决方案1】:

首先,您忘记将simplelist 的元素命名为与它们在simple_vars 中的显示方式相同。因此,当 for() 将值 "a" 传递给 simplelist[["a"]] 时可能会出现错误,因为您在 simplelist 中没有具有此名称的元素。您的错误的另一个来源是赋值符号,您在错误的位置使用了特殊情况 (&lt;&lt;-)。

factor1 <- c("yes", "no","yes","no","no", "yes")
factor2 <- c("Female","Female","Male","Male", "Male", "Female")
a <- sample(1:100, 6, replace=TRUE)
b <- sample(1:100, 6, replace=TRUE)
c <- sample(1:100, 6, replace=TRUE)
d <- sample(1:100, 6, replace=TRUE)
e <- sample(1:100, 6, replace=TRUE)
simpledata <- data.frame(factor1, factor2, a, b, c, d, e)

#list of variable names to loop over
simple_vars = c("a","b","c","d","e")

#initialize list to store results in     
simplelist <- list("a" = "", "b" = "", "c" = "", "d" = "", "e" = "")

for(i in simple_vars){
  simplelist[[i]] <- simpledata %>%
    group_by(factor1, factor2) %>%
    filter(.data[[i]] < 5*median(.data[[i]])) %>%
    filter(between(.data[[i]], mean(.data[[i]])-3*sd(.data[[i]]),
                   mean(.data[[i]])+3*sd(.data[[i]])))
}

【讨论】:

  • 感谢您的帮助!我很欣赏您将列表中的项目命名为与 for 循环中的迭代相匹配的想法,但我认为没有必要——仅
【解决方案2】:

&lt;&lt;- 运算符正在设置一个全局变量,但您不需要这样做。此外,您可以创建大小为零的初始列表并在 for 循环中添加条目。

require(tidyverse)

# make the example dataframe
factor1 <- c("yes", "no","yes","no","no", "yes")
factor2 <- c("Female","Female","Male","Male", "Male", "Female")
a <- sample(1:100, 6, replace=TRUE)
b <- sample(1:100, 6, replace=TRUE)
c <- sample(1:100, 6, replace=TRUE)
d <- sample(1:100, 6, replace=TRUE)
e <- sample(1:100, 6, replace=TRUE)
simpledata <- data.frame(factor1, factor2, a, b, c, d, e)

#list of variable names to loop over
simple_vars = c("a","b","c","d","e")

#initialize list to store results in     
simplelist <- vector(mode="list")

for(i in simple_vars){
    simplelist[[i]] <- simpledata %>%
    group_by(factor1, factor2) %>%
    filter(.data[[i]] < 5*median(.data[[i]])) %>%
    filter(between(.data[[i]], mean(.data[[i]])-3*sd(.data[[i]]),
            mean(.data[[i]])+3*sd(.data[[i]])))
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-20
    • 2019-03-30
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多