【问题标题】:arrange contents in a dataframe extracted from docx in R排列从 R 中的 docx 提取的数据框中的内容
【发布时间】:2021-12-31 15:45:21
【问题描述】:

我有一个文档(.docx),在下面的链接中找到,我使用官员包提取了内容。 https://1drv.ms/w/s!AmwfO49TqaeQhMVx-_pXn-9-3onRRw?e=oe782f

这是文档外观的照片,其中标题 1、2、3 以不同颜色显示。

使用下面的代码,我已经提取了这个文档的内容。

doc <- read_docx("test.docx")
content <- docx_summary(doc)
head(content)

#To get all paragraphs:
par_data <- subset(content, content_type %in% "paragraph") 
par_data <- par_data[, c("doc_index", "style_name", 
                         "text") ]
par_data$text <- with(par_data, {
  substr(
    text, start = 1, 
    stop = ifelse(nchar(text)<30, nchar(text), 30) )
})
par_data

可以使用以下代码复制数据帧。

par_data <- data.frame(doc_index = 1:21, 
                   style_name = c("heading 1", "heading 2", "heading 3",NA ,NA,NA, "heading 2", "heading 3", NA,NA,NA, NA,"heading 2", "heading 3", NA, NA, "heading 1", "heading 2","heading 3", NA,NA ), 
                   text = c(' Cardiovascular drugs ', ' ACE inhibitors. ', ' Valsartan ', ' Valsartan is used to treat hig ', ' Side effects ', ' high potassium; headache, dizz ', ' Beta blockers. ', ' propranolol ', ' Propranolol is prescribed for  ', ' Side effects ', ' slow or uneven heartbeats', ' wheezing or trouble breathing ', ' Calcium channel blockers. ', ' Nifedipine ', ' Side effects ', ' Bloating or swelling of the fa ', ' Neurological drugs ', ' Anticonvulsants ', ' Phenytoin  ', ' Side effects ', ' Decreased coordination, mental '))

我需要将这个数据框重新塑造成这样:

事实上,我需要标题 1 和 2 作为列,其中每种药物(都是标题 3)获取这些列中最后一个标题的文本。另外,我还需要另外两列。有些药物有描述,然后是副作用,而另一些药物只有副作用,在下一个标题 1 或 2 或 3 出现之前的行中。有没有一种简单的方法可以做到这一点?任何帮助表示赞赏。

【问题讨论】:

  • 不要让我们下载一个文件(无论如何它已经被删除了),让我们忘记其中的officer 组件,而只是致力于重塑数据。请将dput(par_data) 的输出发布到代码块中。
  • 仅供参考,您可以将最后一个表达式缩短为par_data$text &lt;- substr(par_data$text, 1, 30);它不会延长较短的字符串,因此它们不受影响。
  • @r2evans 感谢您的帮助。我编辑了问题并提供了数据框的代码。

标签: r dataframe


【解决方案1】:

这不仅仅是重塑,需要基于之前的 textstyle_name 值进行一些推断,以及“最后一次观察结转”(locf)。数据在字符串的开头/结尾也有空格,所以我会用trimws清理它们。

dplyr

我认为这是你想要的:

library(dplyr)
# library(tidyr) # fill
par_data %>%
  mutate(across(where(is.character), trimws)) %>%
  mutate(
    grp = cumsum(is.na(lag(style_name)) & !is.na(style_name)),
    style_name = case_when(
      is.na(style_name) & lag(text) == "Side effects" ~ "sideeffects",
      is.na(style_name) & lag(style_name) == "heading 3" &
        !text %in% "Side effects" ~ "description",
      TRUE ~ style_name)
  ) %>%
  filter(!is.na(style_name)) %>%
  pivot_wider(grp, names_from = "style_name", values_from = "text") %>%
  tidyr::fill(`heading 1`)
# # A tibble: 4 x 6
#     grp `heading 1`          `heading 2`               `heading 3` description                    sideeffects
#   <int> <chr>                <chr>                     <chr>       <chr>                          <chr>      
# 1     1 Cardiovascular drugs ACE inhibitors.           Valsartan   Valsartan is used to treat hig high potas~
# 2     2 Cardiovascular drugs Beta blockers.            propranolol Propranolol is prescribed for  slow or un~
# 3     3 Cardiovascular drugs Calcium channel blockers. Nifedipine  NA                             Bloating o~
# 4     4 Neurological drugs   Anticonvulsants           Phenytoin   NA                             Decreased ~

这个可以在 tidyverse 以外的地方完成,尽管它仍然会受益于外部包函数 (reshape2::dcast) ...stats::reshape 可能有点麻烦与。

数据表

如果您已经在使用(或考虑使用)data.table,则大致相当于上述内容:

library(data.table)
chrs <- which(sapply(par_data, is.character))
as.data.table(par_data)[, c(chrs) := lapply(.SD, trimws), .SDcols = chrs
  ][, grp := cumsum(is.na(shift(style_name)) & !is.na(style_name))
    ][, style_name := fcase(
        is.na(style_name) & shift(text) == "Side effects", "sideeffects",
        is.na(style_name) & lag(style_name) == "heading 3" &
          !text %in% "Side effects", "description",
        rep(TRUE, .N),  style_name)
      ][!is.na(style_name),
        ][, dcast(grp ~ style_name, value.var = "text", data = .SD)
          ][, `heading 1` := zoo::na.locf(`heading 1`)
            ][, .(`heading 1`, `heading 2`, `heading 3`, description, sideeffects) ]
#               heading 1                 heading 2   heading 3                    description                    sideeffects
# 1: Cardiovascular drugs           ACE inhibitors.   Valsartan Valsartan is used to treat hig high potassium; headache, dizz
# 2: Cardiovascular drugs            Beta blockers. propranolol  Propranolol is prescribed for      slow or uneven heartbeats
# 3: Cardiovascular drugs Calcium channel blockers.  Nifedipine                           <NA> Bloating or swelling of the fa
# 4:   Neurological drugs           Anticonvulsants   Phenytoin                           <NA> Decreased coordination, mental

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 2021-11-27
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多