R 将嵌套的数据帧展开为父数据帧
我有一个嵌套在从Mongo获得的数据帧中的数据帧。每行中的行数匹配,因此在查看时,它看起来像一个典型的数据帧。我的问题是,如何将嵌套数据帧扩展到父数据帧中,以便运行dplyr选择?请参见下面的布局R 将嵌套的数据帧展开为父数据帧,r,dataframe,dplyr,tidyr,R,Dataframe,Dplyr,Tidyr,我有一个嵌套在从Mongo获得的数据帧中的数据帧。每行中的行数匹配,因此在查看时,它看起来像一个典型的数据帧。我的问题是,如何将嵌套数据帧扩展到父数据帧中,以便运行dplyr选择?请参见下面的布局 'data.frame': 10 obs. of 2 variables: $ _id : int 1551 1033 1061 1262 1032 1896 1080 1099 1679 1690 $ personalInfo:'data.frame': 10 obs
'data.frame': 10 obs. of 2 variables:
$ _id : int 1551 1033 1061 1262 1032 1896 1080 1099 1679 1690
$ personalInfo:'data.frame': 10 obs. of 2 variables:
..$ FirstName :List of 10
.. ..$ : chr "Jack"
.. ..$ : chr "Yogesh"
.. ..$ : chr "Steven"
.. ..$ : chr "Richard"
.. ..$ : chr "Thomas"
.. ..$ : chr "Craig"
.. ..$ : chr "David"
.. ..$ : chr "Aman"
.. ..$ : chr "Frank"
.. ..$ : chr "Robert"
..$ MiddleName :List of 10
.. ..$ : chr "B"
.. ..$ : NULL
.. ..$ : chr "J"
.. ..$ : chr "I"
.. ..$ : chr "E"
.. ..$ : chr "A"
.. ..$ : chr "R"
.. ..$ : NULL
.. ..$ : chr "J"
.. ..$ : chr "E"
根据建议,以下是如何重新创建数据
id <- c(1551, 1033, 1061, 1262, 1032, 1896, 1080, 1099, 1679, 1690)
fname <- list("Jack","Yogesh","Steven","Richard","Thomas","Craig","David","Aman","Frank","Robert")
mname <- list("B",NULL,"J","I","E","A","R",NULL,"J","E")
sub <- as.data.frame(cbind(fname, mname))
master <- as.data.frame(id)
master$personalInfo <- sub
我们可以循环“personalInfo”,将列表中的NULL元素更改为NA,并将其转换为具有3列的真实数据集
library(tidyverse)
out <- master %>%
pull(personalInfo) %>%
map_df(~ map_chr(.x, ~ replace(.x, is.null(.x), NA))) %>%
bind_cols(master %>%
select(id), .)
str(out)
#'data.frame': 10 obs. of 3 variables:
# $ id : num 1551 1033 1061 1262 1032 ...
# $ fname: chr "Jack" "Yogesh" "Steven" "Richard" ...
# $ mname: chr "B" NA "J" "I" ...
我们可以循环“personalInfo”,将列表中的NULL元素更改为NA,并将其转换为具有3列的真实数据集
library(tidyverse)
out <- master %>%
pull(personalInfo) %>%
map_df(~ map_chr(.x, ~ replace(.x, is.null(.x), NA))) %>%
bind_cols(master %>%
select(id), .)
str(out)
#'data.frame': 10 obs. of 3 variables:
# $ id : num 1551 1033 1061 1262 1032 ...
# $ fname: chr "Jack" "Yogesh" "Steven" "Richard" ...
# $ mname: chr "B" NA "J" "I" ...
虽然@akrun的答案可能更实用,也可能是整理数据的方法,但我认为这个输出更接近您所描述的 我创建了一个新的环境,在那里我放置了data.frame的内容,在那里我将您有问题的列的内容取消列出到所述环境中,最后我将其全部包装回data.frame中 我对cbind使用了一个奇怪的hack,因为.data.frame对列表列很烦人。但是,使用tibble::as_tibble效果很好
new_env <- new.env()
list2env(master,new_env)
list2env(new_env$personalInfo,new_env)
rm(personalInfo,envir = new_env)
res <- as.data.frame(do.call(cbind,as.list(new_env))) # or as_tibble(as.list(new_env))
rm(new_env)
res
# fname id mname
# 1 Jack 1551 B
# 2 Yogesh 1033 NULL
# 3 Steven 1061 J
# 4 Richard 1262 I
# 5 Thomas 1032 E
# 6 Craig 1896 A
# 7 David 1080 R
# 8 Aman 1099 NULL
# 9 Frank 1679 J
# 10 Robert 1690 E
str(res)
# 'data.frame': 10 obs. of 3 variables:
# $ fname:List of 10
# ..$ : chr "Jack"
# ..$ : chr "Yogesh"
# ..$ : chr "Steven"
# ..$ : chr "Richard"
# ..$ : chr "Thomas"
# ..$ : chr "Craig"
# ..$ : chr "David"
# ..$ : chr "Aman"
# ..$ : chr "Frank"
# ..$ : chr "Robert"
# $ id :List of 10
# ..$ : num 1551
# ..$ : num 1033
# ..$ : num 1061
# ..$ : num 1262
# ..$ : num 1032
# ..$ : num 1896
# ..$ : num 1080
# ..$ : num 1099
# ..$ : num 1679
# ..$ : num 1690
# $ mname:List of 10
# ..$ : chr "B"
# ..$ : NULL
# ..$ : chr "J"
# ..$ : chr "I"
# ..$ : chr "E"
# ..$ : chr "A"
# ..$ : chr "R"
# ..$ : NULL
# ..$ : chr "J"
# ..$ : chr "E"
虽然@akrun的答案可能更实用,也可能是整理数据的方法,但我认为这个输出更接近您所描述的 我创建了一个新的环境,在那里我放置了data.frame的内容,在那里我将您有问题的列的内容取消列出到所述环境中,最后我将其全部包装回data.frame中 我对cbind使用了一个奇怪的hack,因为.data.frame对列表列很烦人。但是,使用tibble::as_tibble效果很好
new_env <- new.env()
list2env(master,new_env)
list2env(new_env$personalInfo,new_env)
rm(personalInfo,envir = new_env)
res <- as.data.frame(do.call(cbind,as.list(new_env))) # or as_tibble(as.list(new_env))
rm(new_env)
res
# fname id mname
# 1 Jack 1551 B
# 2 Yogesh 1033 NULL
# 3 Steven 1061 J
# 4 Richard 1262 I
# 5 Thomas 1032 E
# 6 Craig 1896 A
# 7 David 1080 R
# 8 Aman 1099 NULL
# 9 Frank 1679 J
# 10 Robert 1690 E
str(res)
# 'data.frame': 10 obs. of 3 variables:
# $ fname:List of 10
# ..$ : chr "Jack"
# ..$ : chr "Yogesh"
# ..$ : chr "Steven"
# ..$ : chr "Richard"
# ..$ : chr "Thomas"
# ..$ : chr "Craig"
# ..$ : chr "David"
# ..$ : chr "Aman"
# ..$ : chr "Frank"
# ..$ : chr "Robert"
# $ id :List of 10
# ..$ : num 1551
# ..$ : num 1033
# ..$ : num 1061
# ..$ : num 1262
# ..$ : num 1032
# ..$ : num 1896
# ..$ : num 1080
# ..$ : num 1099
# ..$ : num 1679
# ..$ : num 1690
# $ mname:List of 10
# ..$ : chr "B"
# ..$ : NULL
# ..$ : chr "J"
# ..$ : chr "I"
# ..$ : chr "E"
# ..$ : chr "A"
# ..$ : chr "R"
# ..$ : NULL
# ..$ : chr "J"
# ..$ : chr "E"
如果您将数据保存在一个文件夹中,则更容易提供帮助。复制/粘贴str的结果以测试可能的解决方案并不容易。另外,您使用什么函数来获得此结果?该函数中是否没有创建data.frame的选项?这些带有空值的列表在转换时会非常混乱。不是完全重复的列表,但这可能会有所帮助:如果您将数据保存在一个文件夹中,则更容易提供帮助。复制/粘贴str的结果以测试可能的解决方案并不容易。另外,您使用什么函数来获得此结果?该函数中是否没有创建data.frame的选项?这些带有空值的列表转换起来会非常混乱。不是完全重复的,但这可能会有所帮助:你的答案和@Moody_mudscapper的对我来说都很好,谢谢你们的帮助。我把支票放在穆迪的账上,虽然这只是一个与我的想法相似的逻辑流程。您的代码更加简洁,可能是更好的代码,我只是更倾向于思考过程。你可以随意咒骂我的名字。你的回答和@Moody_mudscapper都对我很有用,谢谢你们的帮助。我把支票放在穆迪的账上,虽然这只是一个与我的想法相似的逻辑流程。您的代码更加简洁,可能是更好的代码,我只是更倾向于思考过程。你可以随意诅咒我的名字。