применить регулярное выражение и обновить столбец по фреймам данных - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть два фрейма данных --- таблица A - это таблица шаблонов с именами ссылок, а таблица B - старая таблица имен.Я хочу создать подмножество таблицы B, где она соответствует шаблону в таблице a, и, когда ячейка соответствует, обновить новый столбец в B с помощью столбца обновления в A.

Я ссылался apply regexp водин фрейм данных на основе столбца в другом фрейме данных , но это не решает этот случай.

A <- data.frame(pattern = c("ab", "be|eb", "cc", "dd"), 
                ref = c("first", "second", "third", "forth"))
B <- data.frame(name = c("aa1", "bb1", "cab", "ccaa" "abed" ,"ddd", "ebba"))
B$new = ""

И я хочу, чтобы моя таблица результатов была:

name       new
cab        first
abed       second
ccaa       third
ddd        forth
ebba       second

Я пытался

for (i in 1:nrow(B)) {
  if (as.data.table(unlist(lapply(A$pattern, grepl, B$name))) == TRUE) {
    B$new[i] = A$update
  }
}

Кто-нибудь знает лучшее решение?Я предпочитаю использовать apply family, но понятия не имею, как добавить в него колонку.Любая помощь приветствуется!

Ответы [ 3 ]

0 голосов
/ 18 сентября 2018
# Your data
A <- data.frame(pattern = c("ab", "be|eb", "cc", "dd"), 
            ref = c("first", "second", "third", "fourth"), stringsAsFactors = F)
B <- data.frame(name = c("aa1", "bb1", "cab", "ccaa", "abed" ,"ddd", "ebba"), stringsAsFactors = F)

patternfind <- function(i){
  ifelse(grepl(A$pattern[[i]], B$name), A$ref[[i]], NA) 
} # grepl function for your apply

m = sapply(seq_along(A$pattern), patternfind) # apply function 

test <- cbind(B,m) #bind your pattern matrix to B
melt(test, id = c("name"), value.name = "new", na.rm = T) # melt data for output

   name variable    new
3   cab        1  first
5  abed        1  first
12 abed        2 second
14 ebba        2 second
18 ccaa        3  third
27  ddd        4  fourth

Если вы хотите пойти по маршруту data.table.

library(data.table)

DT.A <- as.data.table(A) # set as data tables
DT.B <- as.data.table(B)

ab <- DT.A[, DT.B[grep(pattern, name)], by=.(pattern, new = ref)] # use grep and by, leave out pattern if don't need to see what matched
ab[,c(3,2,1)] # reorder to your desired order
ab[,3:2] # subset to remove the pattern if you decide you don't want to display it

   name    new
1:  cab  first
2: abed  first
3: abed second
4: ebba second
5: ccaa  third
6:  ddd  fourth
0 голосов
/ 18 сентября 2018

Вы можете использовать stack с sapply:

stack(setNames(sapply(A$pattern,grep,B$name,value=T),A$ref))

  values    ind
1    cab  first
2   abed  first
3   abed second
4   ebba second
5   ccaa  third
6    ddd  forth

Вы также можете использовать stack(setNames(Vectorize(grep)(A$pattern,B[1],value=T),A$ref))

0 голосов
/ 18 сентября 2018

Я отредактировал свой ответ, так как забыл добавить строку, чтобы сначала изменить матрицу B на матрицу:

B <- as.matrix(B,ncol=1) 

теперь должно работать правильно:

library(reshape2)
L <- apply(A, 1, function(x) B[grepl(x[1],B),])
names(L) <- A$ref
result <- melt(L)
colnames(result) <- c('Name','New')

    result
#  Name    New
#1  cab  first
#2 abed  first
#3 abed second
#4 ebba second
#5 ccaa  third
#6  ddd  forth
...