使用 r 中的 dplyr 将纯文本转换为数据框
converting plain text to data frame using dplyr in r
我正在尝试使用 r 将使用 pdftools 和 tidyverse 从 pdf 抓取的纯文本转换为数据框。我希望有一个使用 tidyverse 包的解决方案。我使用以下代码获取包含我的基本信息的字符串列表:
library(tidyverse)
library(pdftools)
textdf <- pdf_text("raw pdf.pdf")
all_stats_lines <- textdf[3:28]%>%
str_squish()%>%
str_replace_all(",", "")%>%
str_remove_all("\+80% \+80% \+80% \+40% \+40% \+40% Baseline Baseline Baseline \-40% \-40%
\-40% \-80% \-80% \-80% Sun Feb 16 Sun Mar 8 Sun Mar 29 Sun Feb 16 Sun Mar 8 Sun Mar 29 Sun Feb
16 Sun Mar 8 Sun Mar 29")%>%
str_remove_all("compared to baseline")%>%
strsplit(" ")
这会产生以下 26 个字符串列表,格式如下:
[[1]]
[1] "Alaska Variable 1 Variable 2 Variable 3 42 15 5"
[2] "Variable 4 Variable 5 Variable 6 43 30 11"
[3] "Alabama Variable 1 Variable 2 Variable 3 27 9 79"
[4] "Variable 4 Variable 5 Variable 6 20 23 4 "
[[2]]
[1] "Arizona Variable 1 Variable 2 Variable 3 40 17 7"
[2] "Variable 4 Variable 5 Variable 6 41 33 10"
[3] "Arkansas Variable 1 Variable 2 Variable 3 29 7 81"
[4] "Variable 4 Variable 5 Variable 6 22 27 7 "
... etc.
注意子列表第 1 行和第 3 行开头的状态名称以及变量名称中的空格。每个状态应该是一行。应该有 6 列变量 1 变量 2 变量 3 变量 4 变量 5 变量 6 并依次对应相应的值。
关于如何构建这个 table 的任何解决方案?
要执行此操作,您需要解决几个问题。
- 将文本拆分为多列
- 组合行对
- 组合列表
如果您只打算这样做一次,那么将您的数据复制到 Excel 中,在那里格式化,然后将其加载到 R 中可能会更简单。但是如果您致力于使用 R,然后我们需要按顺序完成每一个:
1) 文本到列
strsplit(string, " ")
将在 space 上拆分文本字符串。 strsplit(string, "[[:space:]]+")
将在白色 space 上拆分,将连续的白色 space 视为单个拆分。但是,您要避免将 "Variable 1" 分隔为 "Variable" 和“1”,并将 "North Dakota" 分隔为 "North" 和 "Dakota"
此处的一个快速解决方案是 gsub("North ", "North_", string)
,它将 "North Dakota" 变成 "North_Dakota",因此当您应用 strsplit
.
时,这两个词会保持在一起
2) 组合行对
您可以使用取模来提取向量的每个第二个条目:1:4 %% 2
将 return c(1,0,1,0)
。这可用于提取每隔一个值,如下所示:vec[1:4 %% 2 == 1]
.
将它们成对组合可以得到如下结果:
vec = c('a', 'b', 'c', 'd')
paste(vec[1:4 %% 2 == 1], vec[1:4 %% 2 == 0])
3) 组合列表
这里最简单的解决方案可能是 unlist
。但是您也可以使用 purrr
包中的 reduce
函数。
全部结合起来
data = unlist(data)
data = trimws(data)
nn = length(data)
data = paste(data[1:nn %% 2 == 1], data[1:nn %% 2 == 0])
# add other rules here for state names that are two words
data = gsub("ariable ", "ariable_", data)
data = gsub("North ", "North_", data)
data %>%
strsplit("[[:space:]]+") %>%
purrr::reduce(rbind) %>%
as.data.frame()
我正在尝试使用 r 将使用 pdftools 和 tidyverse 从 pdf 抓取的纯文本转换为数据框。我希望有一个使用 tidyverse 包的解决方案。我使用以下代码获取包含我的基本信息的字符串列表:
library(tidyverse)
library(pdftools)
textdf <- pdf_text("raw pdf.pdf")
all_stats_lines <- textdf[3:28]%>%
str_squish()%>%
str_replace_all(",", "")%>%
str_remove_all("\+80% \+80% \+80% \+40% \+40% \+40% Baseline Baseline Baseline \-40% \-40%
\-40% \-80% \-80% \-80% Sun Feb 16 Sun Mar 8 Sun Mar 29 Sun Feb 16 Sun Mar 8 Sun Mar 29 Sun Feb
16 Sun Mar 8 Sun Mar 29")%>%
str_remove_all("compared to baseline")%>%
strsplit(" ")
这会产生以下 26 个字符串列表,格式如下:
[[1]]
[1] "Alaska Variable 1 Variable 2 Variable 3 42 15 5"
[2] "Variable 4 Variable 5 Variable 6 43 30 11"
[3] "Alabama Variable 1 Variable 2 Variable 3 27 9 79"
[4] "Variable 4 Variable 5 Variable 6 20 23 4 "
[[2]]
[1] "Arizona Variable 1 Variable 2 Variable 3 40 17 7"
[2] "Variable 4 Variable 5 Variable 6 41 33 10"
[3] "Arkansas Variable 1 Variable 2 Variable 3 29 7 81"
[4] "Variable 4 Variable 5 Variable 6 22 27 7 "
... etc.
注意子列表第 1 行和第 3 行开头的状态名称以及变量名称中的空格。每个状态应该是一行。应该有 6 列变量 1 变量 2 变量 3 变量 4 变量 5 变量 6 并依次对应相应的值。
关于如何构建这个 table 的任何解决方案?
要执行此操作,您需要解决几个问题。
- 将文本拆分为多列
- 组合行对
- 组合列表
如果您只打算这样做一次,那么将您的数据复制到 Excel 中,在那里格式化,然后将其加载到 R 中可能会更简单。但是如果您致力于使用 R,然后我们需要按顺序完成每一个:
1) 文本到列
strsplit(string, " ")
将在 space 上拆分文本字符串。 strsplit(string, "[[:space:]]+")
将在白色 space 上拆分,将连续的白色 space 视为单个拆分。但是,您要避免将 "Variable 1" 分隔为 "Variable" 和“1”,并将 "North Dakota" 分隔为 "North" 和 "Dakota"
此处的一个快速解决方案是 gsub("North ", "North_", string)
,它将 "North Dakota" 变成 "North_Dakota",因此当您应用 strsplit
.
2) 组合行对
您可以使用取模来提取向量的每个第二个条目:1:4 %% 2
将 return c(1,0,1,0)
。这可用于提取每隔一个值,如下所示:vec[1:4 %% 2 == 1]
.
将它们成对组合可以得到如下结果:
vec = c('a', 'b', 'c', 'd')
paste(vec[1:4 %% 2 == 1], vec[1:4 %% 2 == 0])
3) 组合列表
这里最简单的解决方案可能是 unlist
。但是您也可以使用 purrr
包中的 reduce
函数。
全部结合起来
data = unlist(data)
data = trimws(data)
nn = length(data)
data = paste(data[1:nn %% 2 == 1], data[1:nn %% 2 == 0])
# add other rules here for state names that are two words
data = gsub("ariable ", "ariable_", data)
data = gsub("North ", "North_", data)
data %>%
strsplit("[[:space:]]+") %>%
purrr::reduce(rbind) %>%
as.data.frame()