R表示绕整洁管的循环

时间:2019-01-15 11:41:11

标签: r

我有一个示例数据集,如下所示:

var_a <- vector(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, ....)
# var1 to var8 are vectors that contain pseudorandom numbers between 1 and 20 (unlike var_a not in any particular order). 
data <- data.frame(cbind(var_a, var1, var2, var3, var4, var5, var6, var7, var8))

我想使用列变量“ var_a”(实际上包含1-127的数字)遍历该数据集。对于var_a中的每个数字,我想计算“ var1”至“ var8”中数字的8 x 8相关矩阵,并将127个相关矩阵存储在列表中。

我使用tidyverse管道计算了var_a = 1的第一个相关矩阵:

data %>%
  filter(var_a==1) %>%
  select("var1", "var2", "var3", "var4", "var5", "var6", "var7", "var8")%>%
  cor()

现在,对我而言,最困难的部分是计算var_a = 1,var_a = 2,var_a = 3,....,var_a = 127的相关矩阵并将这些矩阵存储在列表中。

我的尝试如下,但是我陷入了循环遍历和存储相关矩阵的部分:

n <- 127
corlist <- list()
for (i in 1:n) {
      data %>%
       filter(var_a==i) %>%
       select("var1", "var2", "var3", "var4", "var5", "var6", "var7", "var8") %>%
       corlist[i] <- cor()
}

"Error in is.data.frame(x) : argument "x" is missing, with no default"

我是否需要先为cor()定义一个函数,然后将其集成到管道和循环中?

非常感谢帮助/文献/链接!非常感谢你!

1 个答案:

答案 0 :(得分:0)

您不需要为此的for循环。如评论中已经提到的,您可以使用group_by

library(tidyverse)

my.df.cor <- my.df %>% 
  group_by(var_a) %>%  
  nest() %>% # Stores var1 to var8 in a dataframe for each var_a
  mutate(cor = map(data, cor)) # apply the function cor() to this data for each var_a

my.df.cor 
# A tibble: 3 x 3
#   var_a data             cor          
#   <dbl> <list>           <list>       
# 1     1 <tibble [8 x 8]> <dbl [8 x 8]>
# 2     2 <tibble [8 x 8]> <dbl [8 x 8]>
# 3     3 <tibble [8 x 8]> <dbl [8 x 8]>

您收到一个包含3列的小标题,其中数据为每个var_a存储var1至var8,并存储对应的相关矩阵。

pull(my.df.cor, cor)

为您提供所需的胸甲。

您可以使用

修复for循环
n <- 3
corlist <- list()
for (i in 1:n) {
  corlist[[i]] <- my.df %>%
    filter(var_a == i) %>%
    select("var1", "var2", "var3", "var4", "var5", "var6", "var7", "var8") %>%
    cor() 
}

您的代码中的问题是管道在下一行中将data.frame作为第一个参数插入,但是您尝试进行分配,因此cor()没有得到参数。 我先分配任务,然后再分配给该列表项(用[[i]]而不是[i]索引)

数据

var_a <- c(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3)

set.seed(42)
my.df <- data.frame(var_a = var_a, 
                    var1 = sample(1:20, length(var_a), replace = TRUE), 
                    var2 = sample(1:20, length(var_a), replace = TRUE), 
                    var3 = sample(1:20, length(var_a), replace = TRUE), 
                    var4 = sample(1:20, length(var_a), replace = TRUE), 
                    var5 = sample(1:20, length(var_a), replace = TRUE), 
                    var6 = sample(1:20, length(var_a), replace = TRUE), 
                    var7 = sample(1:20, length(var_a), replace = TRUE), 
                    var8 = sample(1:20, length(var_a), replace = TRUE))