重新排列R列表

时间:2014-09-04 17:05:10

标签: r

假设我有一个这样的结构列表。

list(
    a = list(
        a1 = c(1, 2),
        b1 = c(2, 3)
    ),

    b = list(
        a1 = c(3, 4),
        b1 = c(4, 5)
    )
)

我可以使用核心R函数巧妙地使用而不使用应用程序或递归函数将其转换为以下内容吗?

list(
    a1 = list(
        a = c(1, 2),
        b = c(3, 4)
    ),

    b1 = list(
        a = c(2, 3),
        b = c(4, 5)
    )
)

使用stack()删除内部索引。 使用unlist()将两个索引合并在一起。

3 个答案:

答案 0 :(得分:2)

行。这是一次尝试:

L1 <- stack(unlist(L, recursive = FALSE))
L2 <- cbind(L1, do.call(rbind, strsplit(
  as.character(L1$ind), ".", fixed = TRUE)))
c(by(L2[c("values", "1")], L2[["2"]], 
   FUN = function(x) split(x[["values"]], x[["1"]])))
# $a1
# $a1$a
# [1] 1 2
# 
# $a1$b
# [1] 3 4
# 
# 
# $b1
# $b1$a
# [1] 2 3
# 
# $b1$b
# [1] 4 5

我已将by的输出与c包装在一起,以移除与by相关的attributes并将输出返回到基本list。< / p>

答案 1 :(得分:1)

您可以利用列表为environment的事实,并使用within

x就是清单。

> within(x, { a$b1 <- b$a1; b$a1 <- a$b1-1 })
$a
$a$a1
[1] 1 2

$a$b1
[1] 3 4


$b
$b$a1
[1] 2 3

$b$b1
[1] 4 5

以下是一些可能感兴趣的其他事情不确定为什么人们似乎远离基础R功能。他们非常在这些类型的问题中有用(并且它们使Ananda的所有循环都起作用;-)。

每个人都忘了递归连接...

> str(x)
List of 2
 $ a:List of 2
  ..$ a1: num [1:2] 1 2
  ..$ b1: num [1:2] 2 3
 $ b:List of 2
  ..$ a1: num [1:2] 3 4
  ..$ b1: num [1:2] 4 5

仅从str(x)起,您就可以在列表中规划路线。在您的列表中,这是[2:1][1:2]撤消。顺便说一句R是矢量化的!

这些东西也很有用..

> do.call("names", list(c(x)))
#[1] "a" "b"
> do.call("names", list(c(x,recursive=TRUE)))
#[1] "a.a11" "a.a12" "a.b11" "a.b12" "b.a11" "b.a12" "b.b11" "b.b12"
> do.call("c", list(c(x,recursive=TRUE)))
#a.a11 a.a12 a.b11 a.b12 b.a11 b.a12 b.b11 b.b12 
#    1     2     2     3     3     4     4     5 
> do.call("c", list(c(x,recursive=TRUE,use.names=FALSE)))
#[1] 1 2 2 3 3 4 4 5
> do.call("as.expression", list(c(x)))
# expression(a = list(a1 = c(1, 2), b1 = c(2, 3)), b = list(a1 = c(3, 4), b1 = c(4, 5)))
> do.call("as.expression", list(c(x,recursive=TRUE)))
# expression(1, 2, 2, 3, 3, 4, 4, 5)

你会想要进行某种递归,.Primitive函数完全用C语言编码,它们并不是很慢。

在这里,我想要改变你想要改变的矢量。

> c(x,recursive=TRUE)[3:6]
# a.b11 a.b12 b.a11 b.a12 
#     2     3     3     4 

答案 2 :(得分:0)

m <- do.call(rbind, ll) ;m2 <- split(m, col(m))  # that transposes the data
names(m2) <- names(ll[[1]])        # these two steps "transpose" the names
lapply(m2, setNames, names(ll) )

$a1
$a1$a
[1] 1 2

$a1$b
[1] 3 4


$b1
$b1$a
[1] 2 3

$b1$b
[1] 4 5