有没有一种方法可以优化此代码,因为这需要花费数小时才能执行

时间:2020-02-05 14:07:12

标签: r

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 个答案:

答案 0 :(得分:1)

如上所述,您的代码可能存在问题,但是已经回答了问题的“如何加速”部分:

您可以摆脱两个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

答案 1 :(得分:0)

如果您要在不同的列和行中搜索一个字符串匹配项,并将该匹配项的结果另外保存在原始行索引中,则以下内容可能会有所帮助:

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)
  })

答案 2 :(得分:0)

首先,生成sdata的副本数据帧以添加其他列。

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

然后可以使用lapplypmatch函数:

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则进行部分匹配。

请让我知道结果。