我有一个像这样的数据框
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)
)
)
我可以使用嵌套的lapply
和split
来实现它,但我认为应该有一种更简单的方法来实现它。
任何帮助都将不胜感激。
答案 0 :(得分:1)
两种方法 - 一种使用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的回答有助于回答这个问题。
答案 1 :(得分:0)
一个解决方案,split
和嵌套*apply
的数量有限:
lapply(split(df, df$id), function(x) setNames(apply(x, 1L, function(x) as.list(x["value"])), x[["key"]]))
嵌套lapply
和split
替代方案:
lapply(split(df, df$id), function(x) lapply(split(x["value"], x$key), as.list))
欢迎改进!