将列表(带嵌套向量)反规范化/强制为R中的data.frame
我在读一个yaml文件,比如将列表(带嵌套向量)反规范化/强制为R中的data.frame,r,purrr,R,Purrr,我在读一个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
- 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]
)
)
l这是可行的,但不太理想,因为(a)需要处理新data.frame中的每个向量,以及(b)每个向量的类型是明确的(例如,purrr:map\u chr
vspurrr:map\u int
)
#步骤1:确定需要复制“父”行的时间。
人均价值%
purrr::修改深度(2,长度)%>%
purrr::map_int(“值”)
#步骤2:拉出父行并复制元素以匹配'time'。
id_已复制%
purrr::映射int(“个人id”)%%>%
代表(次数=每个人的价值)
名称\u已复制%
purrr::map_chr(“人名”)%%>%
代表(次数=每个人的价值)
#步骤3:拉出嵌套/子行。
时间%
purrr::修改深度(1,“时间”)%>%
purrr::flatten_int()
价值%
purrr::修改深度(1,“值”)%>%
purrr::展平
#步骤4:在数据帧中组合向量。
数据帧(
person\u id=id\u复制,
人名=人名,
时间=时间,
价值=价值
)
为了补充@lmo和@submartingale的想法/方法,这里有一个purrr/tidyverse版本,它将每个嵌套列表转换为data.frame/tible(通过复制name&id的父元素),然后将它们堆叠成单个tible
l %>%
purrr::map_df(tibble::as_tibble)
感谢大家提出了如此简洁和概括的东西。一个简单的base R方法是使用lappy
和data.frame
返回data.frames列表,然后使用do.call
和rbind
将data.frames组合成单个data.frames对象
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
请注意,人名和值将是因子向量,这可能会让人讨厌。如果需要,可以使用stringsAsFactors
参数将这些转换为字符向量
do.call(rbind, lapply(l, data.frame, stringsAsFactors=FALSE))
打印的输出看起来是一样的,但这两个变量的基本数据类型发生了变化。这里有一个简单的base R单行:do.call(rbind,lappy(l,data.frame))
@lmo,太棒了。我喜欢lappy()
如何复制person\u id
和person\u name
的父变量。如果你将此作为回应,我很乐意投票表决。
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
do.call(rbind, lapply(l, data.frame, stringsAsFactors=FALSE))