【问题标题】:R unlist changes namesR unlist 更改名称
【发布时间】:2016-02-02 20:57:11
【问题描述】:

给定以下列表:

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 并不理想。此行为是否在帮助页面中的任何地方进行了解释?可以修改吗?

可以将 unlist 配置为保留名称,以便我的结果是:

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

【问题讨论】:

  • 您确定要一个具有重复名称的命名向量吗?您将如何准确地进行子集化?试试c(y=1, y=2)["y"] 看看糟糕的编程方法造成的歧义。
  • 意识到这一点 - thnx

标签: r list


【解决方案1】:

我们可以尝试在取消列出后设置名称。我们还使用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" 进行子集化,R 仅输出第一个实例:

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

【讨论】:

  • 最好使用unlist(l, use.names=FALSE) 以避免不必要地创建字符向量(例如,n=1e5; l = list(a=1:n) 的速度提高了 100 倍,尽管在微秒时间尺度上)。
  • setNames()代替names(l) =rep( names(l), lengths(l))有什么区别?
【解决方案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 

【讨论】:

    猜你喜欢
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-01
    • 1970-01-01
    • 2022-01-03
    • 2015-05-28
    • 2019-08-13
    相关资源
    最近更新 更多