首页 > 解决方案 > R 将数据帧绑定到前一个数据帧(基于条件)

问题描述

我有一个包含超过 17,000 个数据框的列表。

在提取数据之前,我无法将它们全部绑定在一起,因为每个 df 代表关于一个人的信息。

一些 dfs 只是前面 df 的延续(例如,Df[[1001]] 是 Df[[1000]] 上呈现的数据的延续。

有没有办法将第一行 df 绑定到紧接之前索引的 df (基于条件)?

示例输入:

df1 <- data.frame(text = c("Name: Joseph", "a", "b"))
df2 <- data.frame(text = c("c", "d"))
df3 <- data.frame(text = c("Name: Paul", "e", "f"))
df4 <- data.frame(text = c("Name: Ian", "g", "h"))
df5 <- data.frame(text = c("k", "l"))

df_list <- list(df1, df2, df3, df4, df5)

期望的结果:

[[1]] text "Name: Joseph", "a", "b", "c", "d" 

[[2]] text "Name: Paul", "e", "f"

[[3]] text "Name: Ian", "g", "h", "k", "l"

我可以隔离必须与此代码绑定的 dfs:

library(purrr)

continue <- keep(df_list, ~all(!str_detect(.x$text, "Na.+")))

谢谢。

标签: rlistdataframeconditional-statementsrbind

解决方案


我们可以使用tidyverse方法

  1. 将元素绑定list到单个数据集 -bind_rows
  2. 根据“文本”中是否存在“名称:”子字符串创建分组列
  3. 将元素粘贴到“文本”中 -toString由在 2 中创建的组
  4. 将汇总输出提取为向量pull
  5. 转换为list-as.list如果需要
library(dplyr)
library(stringr)
bind_rows(df_list) %>% 
   group_by(grp = cumsum(str_detect(text, 'Name:'))) %>%  
   summarise(out = toString(text)) %>% 
   pull(out) %>%
   as.list

-输出

[[1]]
[1] "Name: Joseph, a, b, c, d"

[[2]]
[1] "Name: Paul, e, f"

[[3]]
[1] "Name: Ian, g, h, k, l"

注意:上面的输出是一个字符串。如果我们需要vector只是包装list而不是toString

bind_rows(df_list) %>% 
   group_by(grp = cumsum(str_detect(text, 'Name:'))) %>%  
   summarise(out = list(text)) %>% 
   pull(out) 

-输出

[[1]]
[1] "Name: Joseph" "a"            "b"            "c"            "d"           

[[2]]
[1] "Name: Paul" "e"          "f"         

[[3]]
[1] "Name: Ian" "g"         "h"         "k"         "l"  

推荐阅读