gpt4 book ai didi

r - 在 R 数据框中解压缩列表

转载 作者:行者123 更新时间:2023-12-04 11:20:52 25 4
gpt4 key购买 nike

我有一个 dataframe,其中一个字段包含不同长度的列表。我想将此字段中列表的每个元素提取到自己的字段中,以便我可以将结果收集到一个长 dataframe 中,每个列表元素每个 id。

这是一个示例 dataframe

dat <- structure(list(id = c("509935", "727889", "864607", "1234243", 
"1020959", "221975"), some_date = c("2/09/1967", "28/04/1976",
"22/12/2017", "7/02/2006", "10/03/2019", "21/10/1935"), df_list = list(
"018084131", c("062197171", "062171593"), c("064601923",
"068994009", "069831651"), c("071141584", "073129537"), c("061498574",
"065859718", "067251995", "069447806"), "064623976")), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -6L))

我已经提供了代码来实现我想要的最终结果,但是,我并没有以 DRY 的方式做到这一点。这是我尝试过的。

res_n是一个函数如下:

res_n <- function(field, n) {
field[n]
}
dat <- dat %>% mutate(res1 = map(df_list, res_n, 1))
dat <- dat %>% mutate(res2 = map(df_list, res_n, 2))
dat <- dat %>% mutate(res3 = map(df_list, res_n, 3))

这将返回一个数据框,其中三个列表元素中的每一个都来自 df_list 各自的列。

由此我可以实现我的目标并产生最终的dataframe结果,如下所示:

dat_final <- gather(dat, test, labno, -df_list, -some_date, -id) %>% 
select(-df_list) %>%
mutate(labno = as.integer(labno)) %>%
filter(!is.na(labno))

为了避免我使用的 DRY 方法,我使用了一个 for 循环来尝试消除重复的代码。我正在努力让它以我需要达到最终结果的方式工作。这是我尝试的 for 循环。

 for (i in 3) {
dat %>% mutate(paste(res, i, sep = '_') = map(results, res_n, i)) }

谁能帮我改进代码以消除产生结果的重复行。

最佳答案

我们可以使用unnest_wider

,而不是使用重复的 map
library(dplyr)
library(tidyr)
library(stringr)
out <- dat %>%
unnest_wider(df_list, names_repair = ~
str_remove(str_c("res", .x), "[.]+"))
out
# A tibble: 6 x 6
# id some_date res1 res2 res3 res4
# <chr> <chr> <chr> <chr> <chr> <chr>
#1 509935 2/09/1967 018084131 <NA> <NA> <NA>
#2 727889 28/04/1976 062197171 062171593 <NA> <NA>
#3 864607 22/12/2017 064601923 068994009 069831651 <NA>
#4 1234243 7/02/2006 071141584 073129537 <NA> <NA>
#5 1020959 10/03/2019 061498574 065859718 067251995 069447806
#6 221975 21/10/1935 064623976 <NA> <NA> <NA>

编辑:基于@Phil 的评论

现在,使用 pivot_longer

reshape 为“long”
out %>% 
pivot_longer(cols = starts_with('res'), values_drop_na = TRUE) %>%
mutate(value = as.integer(value))
# A tibble: 13 x 4
# id some_date name value
# <chr> <chr> <chr> <int>
# 1 509935 2/09/1967 res1 18084131
# 2 727889 28/04/1976 res1 62197171
# 3 727889 28/04/1976 res2 62171593
# 4 864607 22/12/2017 res1 64601923
# 5 864607 22/12/2017 res2 68994009
# 6 864607 22/12/2017 res3 69831651
# 7 1234243 7/02/2006 res1 71141584
# 8 1234243 7/02/2006 res2 73129537
# 9 1020959 10/03/2019 res1 61498574
#10 1020959 10/03/2019 res2 65859718
#11 1020959 10/03/2019 res3 67251995
#12 1020959 10/03/2019 res4 69447806
#13 221975 21/10/1935 res1 64623976

注意:如果我们检查 ?unnest,它表示生命周期已弃用

nest(.data, ..., .key = deprecated())

unnest(data, cols, ..., keep_empty = FALSE, ptype = NULL, names_sep = NULL, names_repair = "check_unique", .drop = deprecated(), .id = deprecated(), .sep = deprecated(), .preserve = deprecated())

?hoist中的描述是

hoist(), unnest_longer(), and unnest_wider() provide tools for rectangling, collapsing deeply nested lists into regular columns.


另外,如果不打算获得中间宽格式,只需使用 unnest_longer

dat %>%
unnest_longer(df_list)
# A tibble: 13 x 3
# id some_date df_list
# <chr> <chr> <chr>
# 1 509935 2/09/1967 018084131
# 2 727889 28/04/1976 062197171
# 3 727889 28/04/1976 062171593
# 4 864607 22/12/2017 064601923
# 5 864607 22/12/2017 068994009
# 6 864607 22/12/2017 069831651
# 7 1234243 7/02/2006 071141584
# 8 1234243 7/02/2006 073129537
# 9 1020959 10/03/2019 061498574
#10 1020959 10/03/2019 065859718
#11 1020959 10/03/2019 067251995
#12 1020959 10/03/2019 069447806
#13 221975 21/10/1935 064623976

或者使用 base R

merge(setNames(stack(setNames(dat$df_list, dat$id))[2:1], 
c("id", "values")), dat[-3])

关于r - 在 R 数据框中解压缩列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58895879/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com