2016-02-02 21 views
4

考慮以下列表:[R不公開姓名變更

l <- list("foo123"=c(1:3), "foo456"=5, "foo789"=8) 
print(l) 
# $foo123 
# [1] 1 2 3 
# 
# $foo456 
# [1] 5 
# 
# $foo789 
# [1] 

當我unlist()名單,名單得到整數,如果它們是重複的追加。

unlist(l) 
# foo1231 foo1232 foo1233 foo456 foo789 
#  1  2  3  5  8 

我想保留名字,所以use.names=FALSE並不理想。這種行爲在幫助頁面的任何地方都有解釋嗎?它可以被修改嗎?

可以不公開進行配置,以便我的結果是保留名稱:

# foo123 foo123 foo123 foo456 foo789 
#  1  2  3  5  8 
+0

您確定要重名名爲向量?你會如何精確的子集?嘗試'c(y = 1,y = 2)[「y」]'來查看不良編程方法所產生的模糊性。 –

+0

意識到這一點 - thnx – Megatron

回答

11

我們可以嘗試unlisting後設置的名稱。我們還使用use.names=FALSE避免創造和改寫名稱的矢量(MartinMorgan):

setNames(unlist(l, use.names=F),rep(names(l), lengths(l))) 
#foo123 foo123 foo123 foo456 foo789 
#  1  2  3  5  8 

但是請注意,在大多數情況下,重名會引起歧義和可能的錯誤。鑑於你的例子,如果我們現在嘗試使用名稱"foo123"右輸出僅第一個實例子集:

o <- setNames(unlist(l, use.names=F),rep(names(l), lengths(l))) 
o["foo123"] 
# foo123 
#  1 
+1

爲了避免不必要地創建字符向量(例如,對於n = 1e5; l = list(a = 1:n),速度提高了100倍,'unlist(l,use.names = FALSE)儘管是在微秒時間範圍內)。 –

+0

謝謝。我會補充 –

2

這並不完全回答你的問題,但你可以考慮另一種是從去list改爲「長」data.framedata.table

這可以通過基於R的stack或從「reshape2」或「data.table」中的melt輕鬆實現。

例子:

stack(l) 
# values ind 
# 1  1 foo123 
# 2  2 foo123 
# 3  3 foo123 
# 4  5 foo456 
# 5  8 foo789 

library(data.table) 
melt(l) 
# value  L1 
# 1  1 foo123 
# 2  2 foo123 
# 3  3 foo123 
# 4  5 foo456 
# 5  8 foo789 

然後,如果你真的想要一個名爲向量,你總是可以做:

o <- data.table::melt(l) 
setNames(o$value, o$L1) 
# foo123 foo123 foo123 foo456 foo789 
#  1  2  3  5  8