1
\$\begingroup\$

I have the following data frame:

real_test <- as.data.frame(matrix(rep(NA, 12), nrow = 4, ncol = 3))
real_test$V1 <- c("1 NA NA NA", "1 2 NA NA", "1 NA 3 NA", "1 2 3 NA")
real_test$V2 <- c(1, 2, 2, 3)
real_test$V3 <- c(1, 1, 1, 1)
names(real_test) <- c("BUCKET", "POS_BREADTH", "freq")

For each element of real_test$BUCKET I want to return the next real_test$BUCKET using the following approach:

This function returns all non-NA elements of any given x

pat <- function(x){
      x <- as.vector(read.table(text = x, sep = " ", colClasses = "numeric"))
      ready <- x[!is.na(x)]
      return(paste(ready, sep = ","))
    }

This function looks for an item with +1 POS_BREADTH

segment <- function(x, y){
  inter <- real_test[colSums(outer(paste("\\b", pat(x), "\\b", sep = ""), real_test$BUCKET, Vectorize(grepl))) == length(pat(x)),]
  inter <- inter[inter$POS_BREADTH == y + 1, c(1,3)]
  return(inter$BUCKET[which.max(inter$freq)])
}

And I use mapply to pass the column names as x and y in a function:

real_test$TARTGET <- mapply(segment, real_test$BUCKET, real_test$POS_BREADTH)

Is there a faster way? The \\bpat(x)\\b is intentional since I want to have a full match in grepl.

\$\endgroup\$
  • \$\begingroup\$ Sometimes a for loop (what you have under the hood of mapply) is necessary to keep your memory usage low. How many rows of real_test do you have in your real application? \$\endgroup\$ – flodel Sep 21 '16 at 0:51
  • \$\begingroup\$ @flodel 200 000 rows. Though, I have 16 GB of RAM \$\endgroup\$ – user23809 Sep 21 '16 at 5:52
  • \$\begingroup\$ Can you show desired result to show your overall goal given your input dataframe? That segment function is very difficult to read as it includes nested fcts: colSums, outer, grepl... \$\endgroup\$ – Parfait Oct 2 '16 at 23:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.