2017-03-17 78 views
0

我試圖運行列表的列表。每行有29個列表,每個列表有6個數字作爲字符串存儲。一個例子如下所示如果在列表中使用if語句列表中的r

dput(M[6000]) 

list(list(c("0", "1", "19", "785", "-3150", "0.90"), c("4", "2", "-1", "5550", "4400", "0.00"), 
    c("1", "3", "6", "3319", "-2558", "1.49"), c("1", "4", "1", "4573", "-435", "1.24"), 
    c("0", "5", "6", "1137", "-2828", "2.28"), c("0", "6", "24", "1668", "-1143", "2.76"), 
    c("1", "7", "2", "2859", "-720", "1.40"), c("1", "8", "23", "420", "-3346", "1.57"), 
    c("1", "9", "26", "2290", "752", "1.23"), c("1", "10", "8", "1208", "-2842", "2.14"), 
    c("0", "11", "11", "-219", "-374", "1.26"), c("0", "12", "3", "-69", "-2403", "2.24"), 
    c("0", "13", "1", "-3488", "-830", "0.17"), c("1", "14", "7", "2102", "-1404", "1.24"), 
    c("1", "15", "3", "1746", "-3481", "1.59"), c("3", "16", "0", "720", "-1425", "0.47"), 
    c("1", "17", "9", "170", "-2257", "3.14"), c("0", "18", "5", "-351", "-1564", "1.08"), 
    c("4", "19", "-1", "5550", "4400", "0.00"), c("3", "20", "1", "3304", "-3448", "1.78"), 
    c("1", "21", "4", "2289", "-1873", "3.13"), c("0", "22", "2", "175", "-3080", "1.28"), 
    c("1", "23", "12", "877", "140", "1.52"), c("0", "24", "8", "871", "-1933", "4.11"), 
    c("0", "25", "9", "3185", "-2548", "1.50"), c("4", "26", "-1", "5550", "4400", "0.00"), 
    c("3", "27", "2", "-290", "3415", "0.56"), c("4", "28", "-1", "5550", "4400", "0.00"), 
    c("0", "29", "32", "2176", "-2145", "1.58"))) 

對於每一行,我想在29所列出運行,僅保存有等於4。對於一個行的第三個元素的列表將是:

if(as.numeric(M[[6000]][[1]][3]) == 4) M[[6000]][[1]] 

我已經試過的東西倒

MP4 <- lapply(M, function(x) if(as.numeric(x[[1]][3]) == 4) x[[1]]) 

沒有運氣就行了。

回答

4

purrr非常擅長這些類型問題:

library(purrr) 
M %>% 
    map(.f = keep, .p = ~ .x[[3]] == "4") 
# [[1]] 
# [[1]][[1]] 
# [1] "1"  "21" "4"  "2289" "-1873" "3.13" 

編輯按您的評論:

讓我們把另一份名單,M_2,來說明這個問題:

M_2 <- c(M, list(list())) 
M_2 %>% 
    map(.f = keep, .p = ~ .x[[3]] == "4") 
# [[1]] 
# [[1]][[1]] 
# [1] "1"  "21" "4"  "2289" "-1873" "3.13" 
# 
# 
# [[2]] 
# list() 

然後簡單地丟棄等於list()名單:

M_2 %>% 
    map(.f = keep, .p = ~ .x[[3]] == "4") %>% 
    discard(identical, list()) 
# [[1]] 
# [[1]][[1]] 
# [1] "1"  "21" "4"  "2289" "-1873" "3.13" 
+0

非常酷!唯一的問題是任何不滿足條件的行仍然通過,但是作爲一個空的「list()」。我如何只保存滿足條件的列表? – mzakaria

+0

@mzakaria看我的編輯 –

0

這裏有一種方法來遍歷列表,並創建一個新的,其根據自己的第三個要素相等的標準節省元素4.

new_dl <- list() 
j <- 1L 
for (l in 1L:length(dl)) { 
    new_dl[[l]] <- list() 
    for (i in 1L:length(dl[[1]])) 
    if (dl[[l]][[i]][3] == 4) { 
     new_dl[[l]][[j]] <- dl[[l]][[i]] 
     j <- j + 1L 
    } 
    j <- 1L 
} 
+0

我可能會提到,這不僅是一個包含29個列表的列表。這是一個有數千個文件的文件。執行你的第一步將其縮減爲一個包含29個列表的列表。 – mzakaria

+0

哦!我已經更新了相應的答案(並且變得相當難看)。但請在下一篇文章之前閱讀更多有關「最低可重複性示例」的內容。 – snoram

3

要使用基礎R,您可以使用Filter

lapply(M, Filter, f = function(x){x[[3]] == '4'}) 

## [[1]] 
## [[1]][[1]] 
## [1] "1"  "21" "4"  "2289" "-1873" "3.13" 

要過濾一個lar的空元素ger列表,Filter兩次:

# using @apom's data from above 
Filter(function(x){length(x) != 0}, 
     lapply(M_2, Filter, f = function(x){x[[3]] == '4'})) 

## [[1]] 
## [[1]][[1]] 
## [1] "1"  "21" "4"  "2289" "-1873" "3.13"