1

EDIT: I've made some progress. So I read up on subsets, and was able to break down my dataframe under a certain condition. Let's say titleCSV[3] consists of file names ("file1", "file2", "file3", etc) and titleCSV[13] contains values (-18, -8, -2, etc). Code below:

titleRMS <- data.frame(titleCSV[3], titleCSV[13])



for(x.RMS in titleRMS[2]){
    x.RMS <- gsub("[A-Za-z]","",r)
    x.RMS <- gsub(" ","",r)
    x.RMS = abs(as.numeric(r))
}

x.titleRMSJudge <- data.frame(titleRMS[1], x.RMS)
x.titleRMSResult <- subset(x.titleRMSJudge, r < 12)

My question now is, what's the best way to print each row of the first column of x.titleRMSResult with a message saying that it's loud? Thanks, guys!

BTW, here is the dput of my titleRMS:

dput(titleRMS)
structure(list(FILE.NAME = c("00-Introduction.mp3", "01-Chapter_01.mp3", 
"02-Chapter_02.mp3", "03-Chapter_03.mp3", "04-Chapter_04.mp3", 
"05-Chapter_05.mp3", "06-Chapter_06.mp3", "07-Chapter_07.mp3", 
"08-Chapter_08.mp3", "09-Chapter_09.mp3", "10-Chapter_10.mp3", 
"11-Chapter_11.mp3", "12-Chapter_12.mp3", "Bonus_content.mp3", 
"End.mp3"), AVG.RMS..dB. = c(-14, -10.74, -9.97, -10.53, -10.94, 
-12.14, -11, -9.19, -10.42, -11.51, -14, -10.96, -11.71, -11, 
-16)), .Names = c("FILE.NAME", "AVG.RMS..dB."), row.names = c(NA, 
-15L), class = "data.frame")


ORIGINAL POST BELOW Newb here! Coding in R. So I am trying to analyze a csv file. One column has 10 rows with different file names, while the other has 10 rows with different values. I want to run the 2nd column into a loop, and if it's greater/less than a certain value, I wanted it to print the associating file name as well as a message. I don't know how to have both columns run in a loop together so that the proper file name prints with the proper value/message. I wrote a loop that ends up checking each value for as many rows as there are in the other column. At the moment, all 10 rows meet the criteria for the message I want to print, so I've been getting 100 messages!

titleRMS <- data.frame(titleCSV[3], titleCSV[13])

for(title in titleRMS[1]){
    title <- gsub(" ","",title)
}

for(r in titleRMS[2]){
    r <- gsub("[A-Za-z]","",r)
    r <- gsub(" ","",r)
    r = abs(as.numeric(r))

    for(t in title){
        for(f in r){
            if (f < 18 & f > 0) {
                message(t, "is Loud!") 
            }
        }
    }
}

And this line of code only prints the first file name for each message:

for(r in titleRMS[2]){
    r <- gsub("[A-Za-z]","",r)
    r <- gsub(" ","",r)
    r = abs(as.numeric(r))
    for(f in r){
        if (f < 18 & f > 0) {
            message(t, "is Loud!") 
        }
    }
}

Can someone throw me some tips or even re-write what I wrote to show me how to get what I need? Thanks, guys!

2 Answers2

1

You're making things hard on yourself. You don't need regex for this, and you probably don't need a loop, at least not through your data frame. Definitely you don't need nested loops. I think this will do what you say you want...

indicesToMessage <- titleRms[, 2] > 0 & titleRms[, 2] < 18
myMessages <- paste(titleRms[indicesToMessage, 1], "is Loud!")

for (i in 1:length(myMessages)) {
  message(myMessages[i])
}

A more R-like way (read: without an explicit loop) to do the last line is like this:

invisible(lapply(myMessages, message))

The invisible is needed because message() doesn't return anything, just has the side-effect of printing to the console, but lapply expects a return and will print NULL if there is none. invisible just masks the NULL.

Edits: Negative data

Since your data is negative, I assume you actually want messages when the absolute value abs() is between 0 and 18. This works for that case.

indicesToMessage <- abs(titleRms[, 2]) > 0 & abs(titleRms[, 2]) < 18
myMessages <- paste(titleRms[indicesToMessage, 1], "is Loud!")
invisible(lapply(myMessages, message))
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • Hey shujaa, thanks for your help. I tried that code, and all it would print is "is Loud!" once. Basically, the first column has file names "file1, file2, file3, etc" and the 2nd column has values "12, 14, 8, etc". I want it to loop through, and if each value is less than 18, I want it to print the file name that value is associated with. For instance, if row 3 has a value of 8, I want it to print "file3 is Loud!". – TwinSpiritRadio May 28 '14 at 21:34
  • @TwinSpiritRadio that's what my code should do. I can't test it though, because I don't have your data. If it's not working, it may be due to the structure of your data. If you edit into your post the output of `dput(titleRms)`, then I can copy/paste to use your data. (Also see [this post on making reproducible questions](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example).) – Gregor Thomas May 28 '14 at 22:28
  • 1
    @TwinSpiritRadio Thanks for doing that. The only problem with my answer is that your data is negative! You said you wanted things >0 and <18 to get messages, but all your values are <0. Glad you figured out a working solution, but check out a loop-less way in my edits. – Gregor Thomas May 29 '14 at 16:51
  • Sorry about that, Shujaa! I had the data as positive when I first wrote the post, but decided to switch when I re-wrote the code. Sorry! If I can ask you of one last thing...in the answer I posted, I wrote a for loop that stores each row of titleRms[,1] that is too loud into a new vector title filesHighRms. How could I apply that loop into your code? It is much shorter in length. – TwinSpiritRadio May 29 '14 at 19:30
  • `filesHighRMS <- titleRMS[indicesToMessage, 1]` will do it. No loops needed. Or you could just do `filesHighRMS <- subset(titleRMS, AVG.RMS > -18 & AVG.RMS < 0, select = "FILE.NAME")`. Look at each object along the way, i.e., `indicesToMessage`, and remember that any dataframe can be subset as `data[rows_to_select, columns_to_select]`. That should help you figure out what's going on. – Gregor Thomas May 29 '14 at 19:53
1

I've figured out my own issue. Here is what I wrote to come to the conclusion I wanted:

titleRMS <- data.frame(titleCSV[3], titleCSV[13])

filesHighRMS <- vector()
x.titleRMSJudge <- data.frame(titleCSV[3], titleCSV[13])
x.titleRMSResult <- subset(x.titleRMSJudge, titleCSV[13] > -12 & titleCSV[15] > -1)

    for(i in x.titleRMSResult[,1]){
    filesHighRMS <- append(filesHighRMS, i, 999)
    }

emailHighRMS <- paste(filesHighRMS, collapse=", ")
blurbHighRMS <- paste("" ,nrow(x.titleRMSResult), " file(s) (" ,emailHighRMS, ") have a high RMS and are too loud.")

Being new to code, I bet there is a simpler way, I'm just glad I was able to work this out on my own. :-)