2017-10-08 52 views
0

我有一个向量v和矩阵m并使用适用于从cor.test函数(相关性vm列之间)提取的结果的子集。控制嵌套列表的结构时适用FUN返回列表或NA

set.seed(1) 
m <- matrix(runif(12), nrow = 3) 
v <- 3:1 

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

这与长度等于列的数目的列表中m嵌套列表 - 和在结构我想作为输出(2级表)。

> str(res) 
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" 
$ :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" 
$ :List of 3 
    ..$ statistic: Named num 0 
    .. ..- attr(*, "names")= chr "S" 
    ..$ p.value : num 0 
    ..$ estimate : Named num 1 
    .. ..- attr(*, "names")= chr "rho" 
$ :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" 

我要筛选的每种cor.test结果,说p.value,内环路申请并返回NA指示过滤的结果(保留结果的长度,这里四个)。

res <- 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) 
}) 

我的问题是,我们现在得到一个3级列表结构

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 

只有从apply的第一个结果是NA结果的结构非常像期望的,显然因为apply则可以容纳未过滤导致结构。

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" 

我试图徒然返回ifelse(tmp$p.value < 0.1, tmp, NA)ifelse(tmp$p.value < 0.1, list(tmp), list(NA))

我发现的唯一的解决办法是分配NAapply外:

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 

很显然,我错过了什么关于适用的内部运作。

+0

我会强烈建议在看“扫帚”包在提取之前将结果简化成一个整齐的数据帧。 –

回答

2

您的问题不在apply,而是在ifelse。如果您使用if() {} else {}相反,它的工作方式,你打算从ifelse

ifelse形状相同返回一个值作为测试

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 

说明文档

+1

我认为您的报价不是说明问题的最佳方式。尝试'ifelse(FALSE,list(list(a = 1,b = 2)),NA)'和'ifelse(TRUE,list(list(a = 1,b = 2)),NA)'。相反,我会说你必须用'ifelse'返回'list(list(...))'的问题。 –

+1

'形状',这不是我的单词选择,在这里是模糊的......当然你说的是对的。你必须返回'list(list(...))'。但据我所知,这是因为'test'是1个元素,所以'return(tmp)'将只返回输出的第一个元素(即列表的第一个元素)。由于OP要保留整个列表,所以OP必须用'ifelse'返回'list(list(...))',这就是为什么'if(condition){} else {}'起作用的原因,因为它不施加*形状*输出。 – CPak

+0

我同意!一个也找到你的解决方案是好的。 _inelse'_ _注意文件的含义并不清楚 –