0

I have a dataframe.

structure(list(CONTENT = c("@_ShankarNath Hey Shankar, thank you for highlighting this to us, it will be taken care.", 
"#deals #Puma Cell Kilter Black Sneakers is selling cheaper at INR 3899 today https://t.co/n9wLwofVzz #jabong"
), MEDIA_PROVIDER = c("TWITTER", "TWITTER")), .Names = c("CONTENT", 
"MEDIA_PROVIDER"), class = "data.frame", row.names = 1:2)

I have an input text file and an output text file. Input file has a field named "CONTENT". From the data frame given above I am passing the sentence through a loop and performing some calculations. In the output file I have a field named "Score", where the a score will be populated. I have to extract the score and store it in an object.

I have written the following codes.

sco <- for (i in 1:nrow(dfa)){
  s <- list()
  filecon <- file("input.txt")
  writeLines(c("Username = ABC","Password = 123",paste("Content = ", dfa$CONTENT[i]),"Delimiter =  "), filecon)
  close(filecon)

# perform all the calculations

  a <- readLines("output.txt")
  get.score <- function(scor) {
    score <- scor[grepl("Score = ", scor)]
      as.numeric(strsplit(score, "Score = ")[[1]][2])
  }
  s <- get.score(a)
  print(s)
  }

The output file looks like this:

c("Content = @_ShankarNath Hey Shankar, thank you for highlighting this to us, it will be taken care.", 
"Delimiter =  ", "Score = 1.978", "Result = Success")

The value of the score get replaced with every iteration, and I am trying to capture the same, before the loop moves on to the second line.

The print score return the values for all the statements. However when I try replacing the print(s) with s the function is returning NULL. I tried using return(s) I am getting an error Error: No function to return from, jumping to the top level.

Not sure where I am going wrong.

6
  • why are you defining a function inside a for-loop? Commented Feb 17, 2016 at 6:53
  • @mtoto since for every input that I provide I get an output generated and pasted. If i dont capture the output and store it, the loop moves on to the second line and I will have a new output where the old output gets replaced. Hence, I thought I should define the function inside the loop itself. Commented Feb 17, 2016 at 6:59
  • @mtoto the print function prints the output on to the screen for every input iterated by the loop Commented Feb 17, 2016 at 7:00
  • Maybe s[i] <- get.score(a), and keep s <- list() outside the for loop ? Commented Feb 17, 2016 at 7:07
  • 1
    you script is wired because ` for` doesn't output anything so ` sco <- for(i in ...` doesn't make any sense Commented Feb 17, 2016 at 8:15

1 Answer 1

1

Without testing it so far, I suggest two alternatives, either using apply or foreach from package foreach as it seems what you would like to write.

get.score <- function(scor) {
    score <- scor[grepl("Score = ", scor)]
    as.numeric(strsplit(score, "Score = ")[[1]][2])
}

sco <- apply(dfa, 1, function(v) {
             filecon <- file("input.txt")
             writeLines(c("Username = ABC","Password = 123",paste("Content = ", v['CONTENT']),"Delimiter =  "), filecon)
             close(filecon)

             # perform all the calculations
             a <- readLines("output.txt")
             get.score(a)
})

This will output a matrix or vector, but depending on the output of get.score this might not be suitable. You can also use lapply

sco <- lapply(dfa$CONTENT, function(v) {
             filecon <- file("input.txt")
             writeLines(c("Username = ABC","Password = 123",paste("Content = ", v),"Delimiter =  "), filecon)
             close(filecon)

             # perform all the calculations
             a <- readLines("output.txt")
             get.score(a)
})

Finally it the for structure is more familiar to you, you can try

library(foreach)
sco <- foreach(v=dfa$CONTENT) %do% {
             filecon <- file("input.txt")
             writeLines(c("Username = ABC","Password = 123",paste("Content = ", v),"Delimiter =  "), filecon)
             close(filecon)

             # perform all the calculations
             a <- readLines("output.txt")
             get.score(a)
}

Not that the foreach package allows you to make parallel computation.

Sign up to request clarification or add additional context in comments.

2 Comments

Many many thanks....was struggling with this since yesterday evening...i did use apply...but within for loop. Your first option with apply worked. I was under the impression, that since i have to iterate over each line probably the for loop is best suited. Many thanks again.
the second should work also now, previously I left ,1 , in the lapply from copy/paste of the apply case

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.