R rbind 一个数据帧到前一个数据帧(基于条件)
R rbind a data frame to a previous dataframe (based on condition)
我有一个包含超过 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.+")))
谢谢。
我们可以使用tidyverse
方法
- 将
list
个元素绑定到一个数据集 - bind_rows
- 根据 'text'
中存在的 'Name:' 子字符串创建分组列
- 将 2
中创建的组在 'text' - toString
中的元素粘贴在一起
- 使用
pull
将汇总输出提取为向量
- 如果需要,转换为
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"
基础 R 选项 -
tmp <- do.call(rbind, df_list)
split(tmp, cumsum(grepl('Name', tmp$text)))
#$`1`
# text
#1 Name: Joseph
#2 a
#3 b
#4 c
#5 d
#$`2`
# text
#6 Name: Paul
#7 e
#8 f
#$`3`
# text
#9 Name: Ian
#10 g
#11 h
#12 k
#13 l
我有一个包含超过 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.+")))
谢谢。
我们可以使用tidyverse
方法
- 将
list
个元素绑定到一个数据集 -bind_rows
- 根据 'text' 中存在的 'Name:' 子字符串创建分组列
- 将 2 中创建的组在 'text' -
- 使用
pull
将汇总输出提取为向量
- 如果需要,转换为
list
-as.list
toString
中的元素粘贴在一起
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"
基础 R 选项 -
tmp <- do.call(rbind, df_list)
split(tmp, cumsum(grepl('Name', tmp$text)))
#$`1`
# text
#1 Name: Joseph
#2 a
#3 b
#4 c
#5 d
#$`2`
# text
#6 Name: Paul
#7 e
#8 f
#$`3`
# text
#9 Name: Ian
#10 g
#11 h
#12 k
#13 l