繁体   English   中英

如何在不丢失结构的情况下将 NESTED 列表强制为双精度(R)

[英]How to coerce NESTED list into double without losing the structure (R)

似乎有很多关于如何将列表转换为双精度的问题,但似乎没有任何东西可以保持列表的结构有效。

我有一个这样的嵌套列表(R 输出):

我的列表

[[1]] 
[1]  1  3  4  8 11 13 17

[[2]] 
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

[[3]]  
[1]  2 14

然后我将此列表传递给 JAGS 以迭代其元素。 在 JAGS 循环中,我想迭代第一个、第二个和第三个元素,然后检索存储在其中的数字,以便在另一个循环中再次迭代。 这意味着我想访问第一个元素的“1 3 4 8 11 13 17”等等。


我用来迭代的 JAGS 脚本中的代码是这样的:

    for (j in 1:subjects) {  # Subject-loop
          for (i in my_list[j]) {  # Trial loop
   .... 

     }
    }

这样做的背景是并非所有受试者都有有效的试验。 所以我需要通过 JAGS 对每个主题的有效试验。

我打算用上面的嵌套列表来做到这一点。 然而,事实证明 JAGS 无法处理列表 - 所以现在我尝试将其转换为 JAGS 可以迭代的东西,而不会丢失哪些试验属于哪个主题的信息。

我需要保持结构正常运行,因此仅将列表转换为单个向量的所有内容都无济于事,因为我无法再对其进行迭代。

有什么建议么? 我试图通过列表,但 JAGS 无法处理,需要一个“双重”。 我也尝试将其转换为矩阵,但未能保持结构。

谢谢!


更新:我试过这个,这有点像矩阵似乎与 JAGS 一起工作

list_as_matrix <- do.call(rbind, my_list)

但是嵌套列表的长度不同,因此矩阵中的空列只是一遍又一遍地填充相同的值。


JAGS 错误代码是:

4 nodes produced errors; first error: 'list' object cannot be coerced to type "double"  

感谢 DaveArmstrong 的输入,更新了答案:

# a list of 6 subjects and their valid trials
subjects_and_their_valid_trials <- list(
  c(1,3,4,8, 11,13,17), 
  c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20), 
  c(2, 14),
  c(1,3,4,8, 11,13,17), 
  c(1,2,3,4,5,6,8,9,10,11,12,13,14,15,17,18,19,20), 
  c(6, 12))

l <- subjects_and_their_valid_trials # make it easier to read

maxlen <- max(sapply(l, length))
mat <- t(sapply(l, function(x)c(x, rep(NA, maxlen-length(x)))))
minvals <- 1
maxvals <- apply(mat, 1, function(x)max(which(!is.na(x))))


# ---- How the JAGS Loop is structured
nSubj_Condition1 <- 6

# Loop for condition 
for (j in 1:nSubj_Condition1) {  #Subject-loop
  
  print( "///---------------------------------- ///")
  print(paste("Subject number", j))
  
  #-------------------------
  # This loop restricts the following loop to valid cases in the matrix
  for (k in 1:maxvals[j]) { 
    
    print(paste("Iterating through trial matrix... step", k))
    
    # This loop loops through the matrix of valid trials for each subjects 
    for (i in mat[j,k]) {
      
      print(paste("A valid trial number is:", i))
    }
  }
}

像这样的东西怎么样:

l <- list(
c(1,3,4,8, 11,13,17), 
c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20), 
c(2, 14))

将您的列表变成一个用NA值填充的矩阵。

maxlen <- max(sapply(l, length))
mat <- t(sapply(l, function(x)c(x, rep(NA, maxlen-length(x)))))

# > mat
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16]
# [1,]    1    3    4    8   11   13   17   NA   NA    NA    NA    NA    NA    NA    NA    NA
# [2,]    1    2    3    4    5    6    7    8    9    10    11    12    13    14    15    16
# [3,]    2   14   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA    NA    NA    NA
# [,17] [,18] [,19] [,20]
# [1,]    NA    NA    NA    NA
# [2,]    17    18    19    20
# [3,]    NA    NA    NA    NA

然后,对于每个主题,识别具有有效数据的第一列和最后一列。

minvals <- 1
maxvals <- apply(mat, 1, function(x)max(which(!is.na(x))))

然后,在您的 JAGS 模型中,您可以从mat中提取适当的值来识别试验编号。

for (j in 1:subjects) {  # Subject-loop
  for (i in minvals[j]:maxvals[j]) {  # Trial loop
     mat[j,i] ## gives you the trial number for each subject 
    
  }
}

您可以映射列表,该列表在将任意函数应用于每个列表成员后返回初始列表(如果需要,也可以递归)。 在基础 R 中,您可以使用lapply()Map()来执行此操作。 包 { purrr } 用各种方便的功能扩展了这个概念。

例子:

## base R
lapply(your_list, function(list_element) {some_JAGS_call(list_element)})

## purrr (plus pipe and formula notation)
your_list %>% map(~ some_JAGS_call(.x))

这个关于 R 和 JAGS 的在线资源可能会有所帮助。

编辑 1例如,如果您需要将my_list从向量列表映射到适合 JAGS 的矩阵列表,您可以lapply (list-apply) 函数as.matrix()

my_list_of_matrices <- lapply(my_list, function(el) as.matrix(el))

(根据您的 JAGS 调用的要求,向as.matrix()提供更多参数。)

编辑 2陷阱:当您在循环中使用单括号索引列表时: for (i in my_list[j]) { # Trial loop您仍将获取列表元素作为列表。 使用双括号: for (i in my_list[[j]])来选择没有粘性列表部分的列表元素(例如矩阵,如果有的话)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM