2017-10-08 47 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'_ _注意文件的含義並不清楚 –