在R中创建一个连续令牌的新列(如n-gram)

时间:2018-01-28 04:17:42

标签: r n-gram

我有这个数据集;

A        B
URBAN    1
PLAN     2

我希望像这样添加新列;

A        A`      B
URBAN    URB     1
URBAN    RBA     1
URBAN    BAN     1
PLAN     PLA     2
PLAN     LAN     2

如何制作A' R?

中的列

3 个答案:

答案 0 :(得分:3)

dat=read.table(text="A        B
URBAN    1
PLAN     2",h=T,stringsAsFactors=F)

 library(zoo)
 d=lapply(dat$A,function(y)
 rollapply(1:nchar(y),3,function(x)substr(y,min(x),max(x))))
 data.frame(dat[rep(dat$B,lengths(d)),],A1=unlist(d),row.names = NULL)
      A B unlist.d.
1 URBAN 1       URB
2 URBAN 1       RBA
3 URBAN 1       BAN
4  PLAN 2       PLA
5  PLAN 2       LAN

答案 1 :(得分:1)

这是一种可行的方法。我相信有更简洁的方法来处理这项工作。但我认为以下情况会如此。对于mydf中的每一行,我应用了substr()来创建三个字母的元素。 Map()部分正在生成元素。由于存在一些非期望的元素,我进一步用另一个lapply()对它们进行了子集化。最后,unnest()拆分每个列表中的元素并创建长格式数据。

library(tidyverse)

mydf %>%
mutate(whatever = lapply(1:nrow(mydf), function(x) {
                     unlist(Map(function(j, k) substr(mydf$A[x], start = j, stop = k),
                             1:nchar(mydf$A[x]), 3:nchar(mydf$A[x])))
                     }) %>%
                  lapply(function(x) x[nchar(x) ==3])) %>%
unnest(whatever)

      A B whatever
1 URBAN 1      URB
2 URBAN 1      RBA
3 URBAN 1      BAN
4  PLAN 2      PLA
5  PLAN 2      LAN

数据

mydf <- structure(list(A = c("URBAN", "PLAN"), B = 1:2), .Names = c("A", 
"B"), class = "data.frame", row.names = c(NA, -2L))

答案 2 :(得分:1)

以下是str_match

的选项
library(stringr)
merge(stack(lapply(setNames(str_match_all(mydf$A, "(?=(...))"),
            mydf$A), `[`, , 2))[2:1], mydf, by.x = 'ind', by.y = 'A')

或使用与tidyverse

类似的想法
library(purrr)
library(dplyr)
mydf %>%
    mutate(Anew = str_match_all(A, "(?=(...))") %>% 
                map(~.x[,2])) %>%
    unnest   
#      A B Anew
#1 URBAN 1  URB
#2 URBAN 1  RBA
#3 URBAN 1  BAN
#4  PLAN 2  PLA
#5  PLAN 2  LAN