Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将列表(带嵌套向量)反规范化/强制为R中的data.frame_R_Purrr - Fatal编程技术网

将列表(带嵌套向量)反规范化/强制为R中的data.frame

将列表(带嵌套向量)反规范化/强制为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

我在读一个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]
  )
)   

l这是可行的,但不太理想,因为(a)需要处理新data.frame中的每个向量,以及(b)每个向量的类型是明确的(例如,
purrr:map\u chr
vs
purrr: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))