我有一个这样的数据框

  id key value
1  x   a     1
2  x   b     2
3  y   a     3
4  y   b     4

read.table(text = "id   key value
x   a   1
x   b   2
y   a   3
y   b   4", header = TRUE, sep = "\t")


我想获得每个id的列表以及每个key的子列表

因此,在我的示例中,预期输出为:

$x
$x$a
$x$a$value
[1] 1

$x$b
$x$b$value
[1] 2

$y
$y$a
$y$a$value
[1] 3

$y$b
$y$b$value
[1] 4

list(
  x = list(
    a = list(value = 1),
    b = list(value = 2)
  ),
  y = list(
    a = list(value = 3),
    b = list(value = 4)
  )
)


我可以使用嵌套的lapplysplit实现它,但是我认为应该有更简单的方法来实现它。

任何帮助,将不胜感激。

最佳答案

总览

两种方法-一种使用base,另一种使用plyr-将数据框按组划分,在每个组上应用函数,然后将结果返回到列表中。

使用base::split.data.frame()后跟lapply()为每个唯一的value-id对提取key元素。

# split data frame
# based on 'id' and 'key' pairs
df.split <-
    split.data.frame(
        x = df
        , f = list( df$id, df$key )
    )
# keep only the value
# element within each list
df.split <-
    lapply(
        X = df.split
        , FUN = function( i )
            i[["value"]]
    )

# view results
df.split
# $x.a
# [1] 1
#
# $y.a
# [1] 3
#
# $x.b
# [1] 2
#
# $y.b
# [1] 4

# end of script #


使用plyr::dlply()可以执行相同的操作,而无需lapply()

# load necessary packages
library( plyr )

# splits df by the 'id' and 'key' variables
# and return the 'value' for each pairing
df.split <-
    dlply(
        .data = df
        , .variables = c( "id", "key" )
        , .fun = function(i) i[["value"]]
    )

# view results
df.split
# $x.a
# [1] 1
#
# $x.b
# [1] 2
#
# $y.a
# [1] 3
#
# $y.b
# [1] 4
#
# attr(,"split_type")
# [1] "data.frame"
# attr(,"split_labels")
# id key
# 1  x   a
# 2  x   b
# 3  y   a
# 4  y   b

# end of script #


@Colonel Beauvel对SO帖子Emulate split() with dplyr group_by: return a list of data frames的回答有助于回答此问题。

07-24 09:52
查看更多