R 在应用FUN返回列表或NA时控制嵌套列表的结构

R 在应用FUN返回列表或NA时控制嵌套列表的结构,r,list,nested,apply,R,List,Nested,Apply,我有一个向量v和矩阵m,并使用apply从cor.test函数中提取结果子集(v和m列之间的相关性) 我想过滤apply循环中的每个cor.test结果,比如p.value,并返回NA以指示过滤结果(保留结果的长度,这里是四个) 我试图返回ifelse(tmp$p.value

我有一个向量
v
和矩阵
m
,并使用apply从
cor.test
函数中提取结果子集(
v
m
列之间的相关性)

我想过滤apply循环中的每个
cor.test
结果,比如p.value,并返回NA以指示过滤结果(保留结果的长度,这里是四个)

我试图返回
ifelse(tmp$p.value<0.1,tmp,NA)
ifelse(tmp$p.value<0.1,list(tmp),list(NA))
都是徒劳的

我找到的唯一解决方案是在
apply
之外分配
NA

res4 <- apply(m, 2, function(x) {
  cor.test(x, v, method = 'spearman', exact = F)[c(1,3,4)]
})
res4[sapply(res4, "[[", 2) > 0.1] <- NA 

res4 0.1]您的问题不在于
apply
,而在于
ifelse
。如果您改用
If(){}else{}
,它将按您所希望的方式工作

res3 <- apply(m, 2, function(x) {
      tmp <- cor.test(x, v, method = 'spearman', exact = F)[c(1,3,4)]
      if (tmp$p.value < 0.1) { return(tmp) } else { return(NA) }
  })

str(res3)
# List of 4
 # $ :List of 3
  # ..$ statistic: Named num 8
  # .. ..- attr(*, "names")= chr "S"
  # ..$ p.value  : num 0
  # ..$ estimate : Named num -1
  # .. ..- attr(*, "names")= chr "rho"
 # $ : logi NA
 # $ :List of 3
  # ..$ statistic: Named num 0
  # .. ..- attr(*, "names")= chr "S"
  # ..$ p.value  : num 0
  # ..$ estimate : Named num 1
  # .. ..- attr(*, "names")= chr "rho"
 # $ : logi NA

res3您的问题不在于
apply
,而在于
ifelse
。如果您改用
If(){}else{}
,它将按您所希望的方式工作

res3 <- apply(m, 2, function(x) {
      tmp <- cor.test(x, v, method = 'spearman', exact = F)[c(1,3,4)]
      if (tmp$p.value < 0.1) { return(tmp) } else { return(NA) }
  })

str(res3)
# List of 4
 # $ :List of 3
  # ..$ statistic: Named num 8
  # .. ..- attr(*, "names")= chr "S"
  # ..$ p.value  : num 0
  # ..$ estimate : Named num -1
  # .. ..- attr(*, "names")= chr "rho"
 # $ : logi NA
 # $ :List of 3
  # ..$ statistic: Named num 0
  # .. ..- attr(*, "names")= chr "S"
  # ..$ p.value  : num 0
  # ..$ estimate : Named num 1
  # .. ..- attr(*, "names")= chr "rho"
 # $ : logi NA

res3我认为你的报价不是说明问题的最佳方式。尝试
ifelse(FALSE,list(list(a=1,b=2)),NA)
ifelse(TRUE,list(list(a=1,b=2)),NA)
。相反,我想说的是,你必须返回
list(list(…)
ifelse
shape
,这不是我的词汇选择,在这里是不明确的……当然你说的是对的。您必须返回
list(list(…)
。但据我所知,这是因为
test
是一个元素,因此
return(tmp)
只返回输出的第一个元素(即列表的第一个元素)。由于OP希望保留整个列表,OP必须使用
ifelse
返回
list(list(…)
,这就是为什么
if(condition){}else{}
工作的原因,因为它不会对输出施加形状。我同意!A也会发现你的解决方案是好的。不清楚您所说的来自
ifelse
的注释文档是什么意思……我认为您的报价不是说明问题的最佳方式。尝试
ifelse(FALSE,list(list(a=1,b=2)),NA)
ifelse(TRUE,list(list(a=1,b=2)),NA)
。相反,我想说的是,你必须返回
list(list(…)
ifelse
shape
,这不是我的词汇选择,在这里是不明确的……当然你说的是对的。您必须返回
list(list(…)
。但据我所知,这是因为
test
是一个元素,因此
return(tmp)
只返回输出的第一个元素(即列表的第一个元素)。由于OP希望保留整个列表,OP必须使用
ifelse
返回
list(list(…)
,这就是为什么
if(condition){}else{}
工作的原因,因为它不会对输出施加形状。我同意!A也会发现你的解决方案是好的。您不清楚
ifelse
中的注释文档是什么意思……我强烈建议在提取之前查看
broom
包,将结果简化为一个整洁的数据框。我强烈建议在提取之前查看
broom
包,将结果简化为一个整洁的数据框提取。
res2 <- apply(m, 2, function(x) {
  tmp <- cor.test(x, v, method = 'spearman', exact = F)[c(1,3,4)]
  ifelse(tmp$p.value < 0.1, list(tmp), NA)
  })

> str(res2)
List of 4
 $ :List of 1
  ..$ :List of 3
  .. ..$ statistic: Named num 8
  .. .. ..- attr(*, "names")= chr "S"
  .. ..$ p.value  : num 0
  .. ..$ estimate : Named num -1
  .. .. ..- attr(*, "names")= chr "rho"
 $ : logi NA
 $ :List of 1
  ..$ :List of 3
  .. ..$ statistic: Named num 0
  .. .. ..- attr(*, "names")= chr "S"
  .. ..$ p.value  : num 0
  .. ..$ estimate : Named num 1
  .. .. ..- attr(*, "names")= chr "rho"
 $ : logi NA
res3 <- apply(m, 2, function(x) {
  tmp <- cor.test(x, v, method = 'spearman', exact = F)[c(1,3,4)]
  ifelse(tmp$p.value > 0.1, list(tmp), NA) #'invert' the test
})

>res3
List of 4
 $ : logi NA
 $ :List of 3
  ..$ statistic: Named num 2
  .. ..- attr(*, "names")= chr "S"
  ..$ p.value  : num 0.667
  ..$ estimate : Named num 0.5
  .. ..- attr(*, "names")= chr "rho"
 $ : logi NA
 $ :List of 3
  ..$ statistic: Named num 6
  .. ..- attr(*, "names")= chr "S"
  ..$ p.value  : num 0.667
  ..$ estimate : Named num -0.5
  .. ..- attr(*, "names")= chr "rho"
res4 <- apply(m, 2, function(x) {
  cor.test(x, v, method = 'spearman', exact = F)[c(1,3,4)]
})
res4[sapply(res4, "[[", 2) > 0.1] <- NA 
res3 <- apply(m, 2, function(x) {
      tmp <- cor.test(x, v, method = 'spearman', exact = F)[c(1,3,4)]
      if (tmp$p.value < 0.1) { return(tmp) } else { return(NA) }
  })

str(res3)
# List of 4
 # $ :List of 3
  # ..$ statistic: Named num 8
  # .. ..- attr(*, "names")= chr "S"
  # ..$ p.value  : num 0
  # ..$ estimate : Named num -1
  # .. ..- attr(*, "names")= chr "rho"
 # $ : logi NA
 # $ :List of 3
  # ..$ statistic: Named num 0
  # .. ..- attr(*, "names")= chr "S"
  # ..$ p.value  : num 0
  # ..$ estimate : Named num 1
  # .. ..- attr(*, "names")= chr "rho"
 # $ : logi NA