适当使用`mapply()`获取矩阵输出

Appropriate use of `mapply()` to obtain matrix output

我想知道如何修改我的 mapply 调用以避免在我的最后一行代码之后得到:Error: $ operator is invalid for atomic vectors

注意:使用matrix(c(1, .1, 2, .2), nrow = 2)只是为了简单起见。

我的预期输出是:

$Trus 
     [,1] [,2]
[1,]  1.0  2.0
[2,]  0.1  0.2

$Yu_Chen
     [,1] [,2]
[1,]  1.0  2.0
[2,]  0.1  0.2

我的可重现代码是:

ctlist <- function(mm, cont=FALSE, pos=1, outcom=1){
  
  mm <- mm[[1]]
  mm[mm$control==cont & mm$post == pos & mm$outcome == outcom, , drop = FALSE]
}

#=========
dinter <- function(m, pos, outcom){
  
  clist <- ctlist(mm=m, cont=TRUE, pos = pos, outcom = outcom)
  tlist <- ctlist(mm=m, cont=FALSE, pos = pos, outcom = outcom)
  
  matrix(c(1, .1, 2, .2), nrow = 2) # For simplicity
}
#=========
L1 = list(Trus = data.frame(control=c(T,F), post=c(1,1), outcome=c(1,1), time=c(2,2)),
          Yu_Chen = data.frame(control=c(F,F,T,T), post=c(1,2,1,2), outcome=c(1,1,1,1), time=c(1,2,1,2)) )

#=========

G <- function(m){
  
input <- rev(expand.grid(outcom = seq_len(max(m$outcom, na.rm = TRUE)), pos = seq_len(max(m$post, na.rm = TRUE))))
 
mapply(dinter, m=m, input$pos, input$outcom)
  
}
#=========

setNames(lapply(L1, G), names(L1))

#Error: $ operator is invalid for atomic vectors
#Called from: ctlist(mm = m, cont = TRUE, pos = pos, outcom = outcom)

函数中有几个问题ctlist

mm <- mm[[1]]

通过提取第一列将 'mm' 更新为 vector。现在,它没有任何暗淡的属性。因此,如果我们执行下一行,它将不起作用,因为这些列不存在,因为它是 vector

mm[mm$control==cont & mm$post == pos & mm$outcome == outcom, , drop = FALSE]

现在,检查 dinter,不清楚为什么 OP 按预期创建了 clisttlist,然后突然创建了 matrix。可以简化为

ctlist <- function(mm, cont=FALSE, pos=1, outcom=1){ 
  mm[mm$control==cont & mm$post == pos & mm$outcome == outcom, , drop = FALSE]
 }


lapply(L1, function(m) {

 input <- rev(expand.grid(outcom = seq_len(max(m$outcom,
      na.rm = TRUE)), pos = seq_len(max(m$post, na.rm = TRUE))))     
      dinter(m, pos = 1, outcom = 1)

 })
#$Trus
#     [,1] [,2]
#[1,]  1.0  2.0
#[2,]  0.1  0.2

#$Yu_Chen
#     [,1] [,2]
#[1,]  1.0  2.0
#[2,]  0.1  0.2

如果我们在 'input$pos'、'input$outcom' 的每个元素上应用 dinter,那么 m 应该相同。在 OP 的代码中,'m' 也是 mapply/Map 的输入。由于'm'是一个data.frame,单位是列。因此,它在列上循环,而 input$pos 和 input$outcom 的循环是单个元素(在 'ctlist' 函数中创建一个问题,它期望 'mm' 作为 data.frame事实上 input$pos 的长度和 'mm' 的列数不同)

lapply(L1, function(m) {

     input <- rev(expand.grid(outcom = seq_len(max(m$outcom, na.rm = TRUE)), pos = seq_len(max(m$post, na.rm = TRUE))))
     
     Map(dinter, MoreArgs = list(m = m), pos = input$pos, outcom = input$outcom)
    

})
#$Trus
#$Trus[[1]]
#     [,1] [,2]
#[1,]  1.0  2.0
#[2,]  0.1  0.2


#$Yu_Chen
#$Yu_Chen[[1]]
#     [,1] [,2]
#[1,]  1.0  2.0
#[2,]  0.1  0.2

#$Yu_Chen[[2]]
#     [,1] [,2]
#[1,]  1.0  2.0
#[2,]  0.1  0.2

如果我们想展平列表,请使用 cdo.call

do.call(c, lapply(L1, function(m) {

 input <- rev(expand.grid(outcom = seq_len(max(m$outcom, 
     na.rm = TRUE)), pos = seq_len(max(m$post, na.rm = TRUE))))
 Map(dinter, MoreArgs = list(m = m), pos = input$pos, 
         outcom = input$outcom)
   }))