2015-06-17 2 views
2

Я создаю набор данных для вычисления совокупных значений для разных комбинаций слов с использованием регулярного выражения. Каждая строка имеет уникальное значение регулярного выражения, которое я хочу проверить на другом наборе данных и найти количество раз, когда оно появилось в нем.Заменить функцию apply с помощью lapply

Первый набор данных (df1) выглядит следующим образом:

word1 word2    pattern 
    air  10  (^|\\s)air(\\s.*)?\\s10($|\\s) 
airport 20 (^|\\s)airport(\\s.*)?\\s20($|\\s) 
    car  30  (^|\\s)car(\\s.*)?\\s30($|\\s) 

Другой набор данных (df2), из которого я хочу, чтобы соответствовать это выглядит как

sl_no query 
    1  air 10  
    2 airport 20 
    3 airport 20 
    3 airport 20 
    3  car 30 

Конечный результат я хочу должен выглядеть как word1 word2 total_occ воздуха 10 1 аэропорт 20 3 автомобиль 30 1

Я могу сделать это с помощью применять в R

process <- 
function(x) 
{ 
    length(grep(x[["pattern"]], df2$query)) 
}   

df1$total_occ=apply(df1,1,process) 

но найти это время принимать, так как мой набор данных довольно большой.

Я узнал, что функция «mclapply» из «параллельного» пакета может использоваться для запуска таких вещей на многоядерных устройствах, для которых я сначала пытаюсь запустить приложение. Его дает мне ошибку говоря

lapply(df,process) 

Error in x[, "pattern"] : incorrect number of dimensions

Пожалуйста, дайте мне знать, какие изменения я должен сделать, чтобы запустить lapply правильно.

+0

Вы итерацию моделей, так что должно быть вашим первым аргументом для 'lapply ', правильно? – Frank

+0

Вот почему вы получаете эту ошибку: 'lapply' будет применять некоторую функцию к каждому элементу списка по очереди; поэтому функция должна иметь возможность работать с элементами списка. Элементами в этом контексте фрейма данных являются его столбцы, поэтому вы просите R применить 'process' к каждому столбцу' df'. – tegancp

ответ

3

Почему не только lapply() по сравнению с pattern?

Здесь я просто вытащил ваш pattern, но это может так же легко быть df$pattern

pattern <- c("(^|\\s)air(\\s.*)?\\s10($|\\s)", 
      "(^|\\s)airport(\\s.*)?\\s20($|\\s)", 
      "(^|\\s)car(\\s.*)?\\s30($|\\s)") 

Использование данных для df2

txt <- "sl_no query 
    1  'air 10'  
    2 'airport 20' 
    3 'airport 20' 
    3 'airport 20' 
    3  'car 30'" 
df2 <- read.table(text = txt, header = TRUE) 

Просто итерацию по pattern непосредственно

> lapply(pattern, grep, x = df2$query) 
[[1]] 
[1] 1 

[[2]] 
[1] 2 3 4 

[[3]] 
[1] 5 

Если вы хотите получить более компактный выход, как было предложено в вашем вопросе, вам нужно будет запустить lengths() над возвращенным результатом (спасибо @Frank за указание новой функции lengths().)). Например

lengths(lapply(pattern, grep, x = df2$query)) 

который дает

> lengths(lapply(pattern, grep, x = df2$query)) 
[1] 1 3 1 

Вы можете добавить это к исходным данным через

dfnew <- cbind(df1[, 1:2], 
       Count = lengths(lapply(pattern, grep, x = df2$query))) 
+0

И после этого 'lengths' на том, если они имеют последнюю версию R – Frank

+1

@Frank Yup; Я просто заметил эту часть Q, поскольку она не была в какой-либо разметке. Добавил это сейчас. –

+1

Хм, я вижу, вы добавили версию с длиной, но вы можете сохранить свой оригинальный способ и просто обернуть его в новую функцию 'lengths', например' lengths (lapply (... и т. Д.))) ' – Frank