2017-03-07 100 views
0

當我根據strsplit()的結果調用strsplit()作爲結果時,我有時會得到一個或兩個「子列表」的分裂。例如,如何訪問R中列表中的可變長度列表

v <- c("50", "1 h 30 ", "1 h", NA) 
split <- strsplit(v, "h") 
[[1]] 
[1] "50" 

[[2]] 
[1] "1" " 30" 

[[3]] 
[1] "1 " 

[[4]] 
[1] NA 

我知道我可以用「[]」和「[]」告訴我那些子列表的內容接入分裂的個人名單,所以我想我理解這一點。我可以通過做[split] [[2]] [2]來訪問[[2]]中的「30」。

不幸的是,我不知道如何通過編程訪問我的整個列。我試圖將列轉換爲數字數據。但那個「1小時30分」的案件給我帶來了很多麻煩。

func1 <- function(x){ 
    split.l <- strsplit(x, "h") 
    len <- lapply(split.l, length) 
    total <- ifelse(len == 2, as.numeric(split.l[2]) + as.numeric(split.l[1]) * 60, as.numeric(split.l[2])) 
    return(total) 
} 

v <- ifelse(grepl("h", v), func1(v), as.numeric(v)) 

我知道len返回分裂長度的向量。但是當涉及到實際訪問單個子列表的第二個元素時,我根本不知道如何正確執行。這會產生一個錯誤,因爲split.l [1]和split.l [2]每次只返回整個原始數據幀列的前兩個元素。 [[1]]和[[2]]也不起作用。我需要[[i]] [1]和[[i]] [2]之類的東西。但我試圖不使用for循環和迭代。

爲了使長話短說,我該如何編程

訪問內部列表元素作爲參考,我沒看這這幫助。但我仍然無法解決它。 apply strsplit to specific column in a data.frame

我真的在R列表和列表處理掙扎,所以任何幫助表示讚賞。

回答

0

一個常見的成語是lapply(l, [, 2),其中施加到你的實施例給出了:如果它能夠

> lapply(split, `[`, 2) 
[[1]] 
[1] NA 

[[2]] 
[1] " 30 " 

[[3]] 
[1] NA 

[[4]] 
[1] NA 

sapply()將崩潰這對一個向量。

正在採取哪些是lapply()需要的split每個組件反過來—這是你的僞代碼—的[[i]]位和每個那些我們想抽取n個元素。我們通過應用[函數和n —在這種情況下2L

如果你想第一個元素,除非有第二個元素,在這種情況下,在第二個,你可以隨便寫的,而不是直接使用[包裝:

wrapper <- function(x) { 
    if(length(x) > 1L) { 
     x[2L] 
    } else { 
     x[1L] 
    } 
} 

lapply(split, wrapper) 

這給

> lapply(split, wrapper) 
[[1]] 
[1] "50" 

[[2]] 
[1] " 30 " 

[[3]] 
[1] "1 " 

[[4]] 
[1] NA 

或許

lens <- lengths(split) 
out <- lapply(split, `[`, 2L) 
ind <- lens == 1L 
out[ind] <- lapply(split[ind], `[`, 1L) 
out 

但遍歷從輸出兩次。