适当使用`mapply()`获得矩阵输出 [英] Appropriate use of `mapply()` to obtain matrix output
问题描述
我想知道如何修改我的 mapply
调用,以避免出现:错误:$运算符对我的最后一行代码无效对原子向量
?
I was wondering how to modify my mapply
call to avoid getting: Error: $ operator is invalid for atomic vectors
after my last line of code?
注意:使用 matrix(c(1,.1,2,.2),nrow = 2)
只是为了简单起见.
Note: the use of matrix(c(1, .1, 2, .2), nrow = 2)
is just for simplicity.
我的预期输出是:
$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
updates the 'mm' to a vector
by extracting the first column. Now, it doesn't have any dim attributes. So, if we do the next line, it won't work because those columns are not present as it is a vector
mm[mm$control==cont & mm$post == pos & mm$outcome == outcom, , drop = FALSE]
现在,检查 dinter
尚不清楚,为什么OP创建了 clist
和 tlist
然后是 matrix
出乎意料.可以用
Now, checking the dinter
, it is unclear, why the OP created the clist
and tlist
and then a matrix
out of the blue as expected. It can be simplified with
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"的列数不同)
If we are applying the dinter
on each element of 'input$pos', 'input$outcom', then the m
should be the same. In the OP's code, 'm' is also an input to mapply/Map
. As 'm' is a data.frame, the unit is a column. So, it loops over the columns, while the loop for input$pos and input$outcom is a single element (creating an issue in the 'ctlist' function which expects 'mm' as a data.frame along with the fact that length of input$pos and the number of columns of 'mm' differ)
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
如果我们想弄平列表,请在 do.call
If we want to flatten the list, use c
with do.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)
}))
这篇关于适当使用`mapply()`获得矩阵输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!