在R中的列中分解(熔化)文本数据?

时间:2013-05-21 11:18:04

标签: r text

我有一个csv文件,其中包含以下格式的数据:

  

PrjID 目标
   1001,(i)提高效率(ii)降低成本(iii)最大化收入
   1002,a)玩得开心b)学习新事物
   1003,(1)变得棘手(2)挑战任务

第一个变量是Id,第二个变量是文本变量“objective”。每个项目都有一个单独列中的多个目标的数据,分别由(i),(ii),..或(a),(b),(c),...等,或(1),(2), (3),..等。现在我希望为项目的每个目标创建一个观察。很像这样:

  

PrjID 目标
   1001,(i)提高效率
   1001,(ii)降低成本
   1001,(iii)最大化收入
   1002,a)玩得开心    1002,b)学习新事物
   1003,(1)变得棘手的    1003,(2)挑战任务

对于只有一个目标的项目,它只有一行。但是对于多个目标,它会将观察结果分开。

我对处理R中的文本数据很陌生,有些R pro可以帮我解决这个问题吗?提前谢谢!

2 个答案:

答案 0 :(得分:4)

这是一个想法。

  1. 使用聪明的正则表达式在目标列中插入新的分隔符
  2. strsplit中使用此分隔符可以在向量中分割句子
  3. 使用by,按ID处理上述步骤。
  4. 按照这个步骤,我得到了这段代码:

    ll <- by(dat,dat$PrjID,FUN = function(x){
            x.delim <- gsub(" (\\(?[a-x,0-9]*\\))",'#\\1',x$Objective)
            obj  = unlist(strsplit(x.delim,'#'))
            data.frame(PrjID= x$PrjID,objective=obj[-1])
    })
    ## transform your list to a data.frame
    do.call(rbind,ll)
    
          PrjID                 objective
    1001.1  1001 (i) To improve efficiency
    1001.2  1001        (ii) Decrease cost
    1001.3  1001   (iii) Maximize revenue 
    1002.1  1002               a) Have fun
    1002.2  1002      b) Learn new things 
    1003.1  1003        (1) Getting tricky
    1003.2  1003      (2) Challanging task
    

    PS,这里 dat 是:

    dat <- read.table(text='PrjID, Objective 
    1001 , (i) To improve efficiency (ii) Decrease cost (iii) Maximize revenue 
    1002 , a) Have fun b) Learn new things 
    1003 , (1) Getting tricky (2) Challanging task',sep=',',header=TRUE)
    

答案 1 :(得分:3)

通过agstudy从答案中得到一个结论,这是一个不使用 magic 分隔符但不保留文本中点的索引的解决方案:

// Matches:
// 1. Single letter prefixes: a), b) ... z)
// 2. Roman numerals (only small case): [i,x,c,m,v]+
// 3. Numeral indexes: [0-9]*
delim <- "((^|\\s)\\(?([a-z]|[i,x,c,m,v]+|[0-9]+)\\))"

ll <- by(dat, dat$PrjID, function (r) {
            each.obj <- str_split(r$Objective, delim)[[1]][-1]
            data.frame(PrjId = r$PrjID, Objective = str_trim(each.obj))
        })

do.call(rbind, ll)

       PrjId                     Objective
1001.1  1001     First(could be something)
1001.2  1001 Seconds (blah something else)
1001.3  1001      (how can thins be) Third
1002.1  1002         To improve efficiency
1002.2  1002                 Decrease cost
1002.3  1002              Maximize revenue
1003.1  1003                Getting tricky
1003.2  1003              Challanging task
在这种情况下,

dat是:

> dat
  PrjID
1  1001
2  1002
3  1003
                                                                                    Objective
1 (i) First(could be something) b) Seconds (blah something else) (3) (how can thins be) Third
2                        (i) To improve efficiency (ii) Decrease cost (iii) Maximize revenue
3                                                     (1) Getting tricky (2) Challanging task