R:将特定行转换为列

时间:2017-11-13 10:56:50

标签: json r dplyr tidyr tidyverse

我从json文件导入了相当混乱的数据,它看起来像这样:

raw_df <- data.frame(text = c(paste0('text', 1:3), '---------- OUTCOME LINE ----------', paste0('text', 4:6), '---------- OUTCOME LINE ----------'),
                              demand = c('cat1', rep('', 2), 'info', 'cat2', rep('', 2), 'info2')
                     )



raw_df
                                text demand
1                              text1   cat1
2                              text2       
3                              text3       
4 ---------- OUTCOME LINE ----------   info
5                              text4   cat2
6                              text5       
7                              text6       
8 ---------- OUTCOME LINE ----------  info2

(BTW,---------- OUTCOME LINE ----------text列中的实际字符串)

我想整理一下,以便它具有以下格式:

final_df
                  text demand outcome
1 text1. text2. text3.   cat1   info1
2 text4. text5. text6.   cat2   info2

最快捷,最有效的方法是什么?谢谢你的提示。

2 个答案:

答案 0 :(得分:2)

A dplyr&amp; tidyr解决方案:

raw_df %>% 
    mutate(outcome = demand,
           demand = replace(demand, demand == '', NA),
           outcome = replace(outcome, outcome == '', NA),
           outcome = gsub("^cat\\d+", NA, outcome)) %>% 
    fill(demand) %>% 
    fill(outcome, .direction = "up") %>% 
    filter(!grepl("-----", text)) %>%
    group_by(demand, outcome) %>% 
    summarize(text = gsub(",", "\\.", toString(text))) %>% 
    select(text, everything())
  • 根据需要修正要显示的文字,替换NA s的空白,并准备结果列。

  • fill默认向下方向的demand列,以及向上方向的结果列。

  • filter根据其连字符排除----- OUTCOME LINE ------

  • group_concat列生成text,然后将默认,.交换出来。

  • select将列添加到所需的序列中。

# A tibble: 2 x 3
# Groups:   demand [2]
                 text demand outcome
                <chr> <fctr>   <chr>
1 text1. text2. text3   cat1    info
2 text4. text5. text6   cat2   info2

答案 1 :(得分:1)

这里我们根据'text'列中-的存在使用'grepl'创建一个逻辑索引,将'raw_df'子集删除这些行,通过获取累积总和来创建一个分组列'将aggregate替换为paste并使用''填充非{ind}',NAna.locf'text'列按'demand'分组NA之前的值。然后,通过使用'indx'

进行子集化,从'demand'创建'结果'
indx <- grepl("-", raw_df$text)
transform(aggregate(text~demand, transform(raw_df[!indx,], 
  demand = zoo::na.locf(replace(demand, demand=="", NA))), toString),
    outcome = raw_df$demand[indx])
#  demand                text outcome
#1   cat1 text1, text2, text3    info
#2   cat2 text4, text5, text6   info2

或者可以使用data.table

完成此操作
library(data.table)
setDT(raw_df)[demand == "", demand := NA][!indx, .(text= paste(text, collapse='. ')),
          .(demand = zoo::na.locf(demand))][, outcome := raw_df$demand[indx]][]