Есть ли способ оптимизировать этот код, так как это занимает часы, чтобы выполнить - PullRequest
0 голосов
/ 05 февраля 2020
for (i in 1:99653)
{
  for(j in 1:3226)
    {
    if (grepl(cdata$LegDigitsDialed[i],sdata$SavedPhone[j]) == TRUE)

        {
          cdata$category[i] = "Supplier"
          cdata$su_name[i] = sdata$sushortname[j]
        }

      else
        {
          cdata$category[i] = "Customer"
          cdata$su_name[i] = "Null"      
        }

    }
}

У меня есть два фрейма данных, и я хочу классифицировать каждый элемент столбца на основе присутствия во втором фрейме данных.

Мои данные выглядят так:

>cdata
LegDigitsDialed
"a"
"b"
"c"


>sdata
SavedPhone
"aa"
"c"

То, что я хочу, это:

LegDigitsDialed     category
"a"                 "Supplier"
"b"                 "Customer"
"c"                 "Supplier"

Таким образом, в основном мой псевдокод является

for (i=1,i<100000,i++)   for(j=1,j<3500,j++)
      {
        if (j contains i) //partial string matching
            populate i(different column) with some value
        else
            populate i(different column) with some other value
      }

, этот скрипт в R выполняется уже более 24 часов, и только одна треть записи были обработаны. Есть ли способ оптимизировать этот код?

Ответы [ 3 ]

1 голос
/ 05 февраля 2020

Как написано выше, возможно, что-то не так с вашим кодом, но он уже отвечает на вопрос «как повысить скорость»:

Вы можете избавиться от обоих циклов for (и, вероятно, будет в тысячу раз быстрее, если вы получите ответы на ваши if вопросы, подобные этим.

vec1 <- c("a", "b")
vec2 <- c("ab", "a", "b", "c")

sapply(vec1, grepl, x = vec2)

Это дает

         a     b
[1,]  TRUE  TRUE
[2,]  TRUE FALSE
[3,] FALSE  TRUE
[4,] FALSE FALSE
0 голосов
/ 05 февраля 2020

Сначала создайте кадр данных реплики sdata для добавления дополнительного столбца.

new.sdata <- sdata
new.sdata$category <- "Supplier"

Затем можно использовать функции lapply и pmatch:

cdata$category <- lapply(cdata$LegDigitsDialed, function(x) new.sdata$category[pmatch(x, sdata$SavedPhone)])
cdata$su_name <- lapply(cdata$LegDigitsDialed, function(x) sdata$sushortname[pmatch(x, sdata$SavedPhone)])
cdata$category[is.na(cdata$category)] = "Customer"
cdata$su_name[is.na(cdata$su_name)] = "Null"

lapply предназначен для итерации всех элементов, а pmatch выполняет частичное сопоставление.

Пожалуйста, дайте мне знать результат.

0 голосов
/ 05 февраля 2020

Если вы ищете одно совпадение строк в другом столбце и строке и дополнительно сохраняете результаты этого совпадения в исходном индексе строки, может помочь следующее:

library(dplyr)
# generate example data
cdata <- data.frame(SavedPhone = c("a_a", "a_b", "a_a", "x_y"),
                LegDigitsDialed = c("a", "b", "c", "a"),
                sushortname = c("Max", "Moritz", "Something", "Max"),
                stringsAsFactors=F)

# run one loop within `dplyr`
cdata %>% 
  do({

    # initialize no match values
    category <- rep("Customer", nrow(.))
    su_name <- rep("NULL", nrow(.))

    # loop through `LegDigitsDialed` column
    for(idx in 1:nrow(.)) {

      # find matching index if possible
      search_idx <- which(grepl(.$LegDigitsDialed[idx], .$SavedPhone)==T)

      # overwrite default value
      category[search_idx] <- "Supplier"
      su_name[search_idx] <- .$SavedPhone[search_idx]
    }

    # return data frame
    data.frame(category=category, su_name=su_name, 
               LegDigitsDialed=.$LegDigitsDialed, SavedPhone=.$SavedPhone,
               stringsAsFactors=F)
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...