我正在阅读像
这样的yaml文件- person_id: 111
person_name: Russell
time:
- 1
- 2
- 3
value:
- a
- b
- c
- person_id: 222
person_name: Steven
time:
- 1
- 2
value:
- d
- e
我想反规范化为:
person_id person_name time value
1 111 Russell 1 a
2 111 Russell 2 b
3 111 Russell 3 c
4 222 Steven 1 d
5 222 Steven 2 e
我有一个解决方案,但我希望有更简洁的东西。这是嵌套列表:
l <- list(
list(
person_id = 111L,
person_name = "Russell",
time = 1:3,
value = letters[1:3]
),
list(
person_id = 222L,
person_name = "Steven",
time = 1:2,
value = letters[4:5]
)
)
关于可能的重复,此问题类似于(1)How to denormalize nested list in R?,但结构不同(round
/ diff
/ saldo
结构与time
/ value
此处)和(2)Split comma-separated column into separate rows,但time
是矢量,而不是像director
这样的逗号分隔元素。我希望这种不同的结构有所帮助。
答案 0 :(得分:1)
Reduce(rbind,lapply(l,data.frame))
答案 1 :(得分:1)
赞美@lmo和@submartingale的想法/方法,这里是一个purrr / tidyverse版本,它将每个嵌套的列表转换为data.frame / tibble(通过复制name&amp; id的父元素),然后将它们堆叠成单个tibble。
l %>%
purrr::map_df(tibble::as_tibble)
感谢各位提出如此简明扼要的内容。
答案 2 :(得分:1)
一个简单的基本R方法是使用lapply
和data.frame
返回data.frames列表,然后使用do.call
和rbind
来合并data.frames到一个data.frame对象。
do.call(rbind, lapply(l, data.frame))
返回
person_id person_name time value
1 111 Russell 1 a
2 111 Russell 2 b
3 111 Russell 3 c
4 222 Steven 1 d
5 222 Steven 2 e
请注意,person_name和value将是因子向量,这可能很烦人。如果需要,可以使用stringsAsFactors
参数将这些转换为字符向量。
do.call(rbind, lapply(l, data.frame, stringsAsFactors=FALSE))
打印输出看起来相同,但这两个变量的基础数据类型已经改变。
答案 3 :(得分:0)
这很有效,但不太理想,因为(a)新data.frame中的每个向量都需要处理,(b)每个向量的类型是显式的(例如,{{ 1}} vs purrr:map_chr
)
purrr:map_int