在 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

如何在 R 中制作 A' 列?

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

这是一种可能的方法。我相信有更简洁的方法来处理这项工作。但我认为以下内容就可以了。对于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))

这是一个带有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

最新更新