I want to loop through an array and match filenames to particular variables.
I am attempting to do so like this:
file.names = c("common", "08f13", "13f08")
for (f in file.names){
if grep("common", f) {
a=f
} else if grep("08f13", f){
b=f
} else
c=f
}
and if common is in the filename I want to assign it to the variable a and if 08 is in the filename assign it to b and so on. Based on the errors I am getting in r I think there is something wrong with the structure of my loop, or I am even using grep incorrectly.
My code returns this error:
Error: unexpected '}' in "}"
file.names = list.files(path, pattern=".prj")
for (f in file.names){
if(grepl("common", f)) {
a=f
} else if(grepl("08", f)) {
b=f
} else {
c=f
}
}
Mistakes:
Round brackets around if, else if blocks
grep returns 1 / 0 which are integers and grepl returns TRUE / FALSE
Related
I have tried the following but the output brings an argument stating,
Error in append("0") : argument "values" is miss
for (rowz in final_data$Ingridients) {
Cobalt_row<-lst()
if (sum(str_detect(rowz, 'Cobalt'))>0) {
Cobalt_row.append(1)
} else {
Cobalt_row<-append(0)
}
print(Cobalt_row)
}
I intended to loop through the list and generate a boolean of ones and twos depending on
whether or not I had the value.
Please help
Without the data, I can't test it, but this should work:
Cobalt_row<-lst()
k <- 1
for (rowz in final_data$Ingridients) {
Cobalt_row[[k]] <- ifelse(str_detect(rowz, 'Cobalt'), 1, 0)
k <- k+1
}
or even simpler if you need a list:
Cobalt_row <- as.list(as.numeric(str_detect(final_data$Ingredients, "Cobalt")))
I am trying to read.csv a series of file named ("year".csv) from year 2005 to 2007 and writing into database.
However the loop command only consist of "2007L" for element "i" and only read 2007.csv into the dataframe.
Any ideas on how to resolve the issue ?
for(i in c(2005:2007)){
ontime<-read.csv(paste0(i,".csv"), header=TRUE)}
if(i == 2005){
dbWriteTable(conn,"ontimet",ontimet)
} else {
dbWriteTable(conn,"ontimet",ontimet, append= TRUE)
}
}
Something like this might be what you need. I think you just need to assign variables and append in the right place.
You probably need is like this. It produces all three years (or in your case, it would be csv's)
tmp = NULL
for(i in c(2005:2007)){
if(i == 2005){
tmp = append(tmp, i)
} else {
tmp = append(tmp, i)
print(tmp)
}
}
I have a recursive function that uses the output of the previous call as the input of the next call:
recurse_foo = function(input) {
if(identical(input, character(0))) return(NULL)
else {
uu = get_incremental_output(input) ## <-- interested in collecting this
return(recurse_foo(uu))
}
}
As is evident, the terminal output is not very interesting, and I am interested in collecting the intermediate output, but I cannot imagine that growing a global list or any other side effect would be elegant (which is the only thing I can think of).
Any other abstractions that might be useful here?
Thanks.
Specific example:
final_countdown = function(input) {
if (input/2 < 1) return(NULL)
else {
uu = input/2 # <-- interested in collecting this
print(uu)
return(final_countdown(uu))
}
}
final_countdown(100)
In this case, I am interested in collecting the sequence of uus that are printed.
This is a solution, if all intermediate outputs are of the same type:
final_countdown = function(input) {
if (input/2 < 1) return(NA)
else {
c(input, final_countdown(input/2))
}
}
I have a function that is supposed to return a matrix for further functions to use. I have it reading in a file and doing calculations, but I need the main function to skip to the next file if the current one does not meet the correct formatting. This is how basically how I have it now:
for (file in list.files(directory)) {
for (i in 1:length(var)) {
matrix <- foo('someFile.txt',var[i]) # returns matrix under normal conditions
if (typeof(matrix)) == "logical") { # check if foo returns FALSE
warning(paste0('File ',file, ' is not formatted correctly'))
break # skip to next file if so
}
...
}
}
foo <- function(input,seq)
data <- readLines(input)
if (!data[1] %in% c("first","line","values")) {
return(FALSE)
}
...
return(data)
}
But testing the class matrix returns seems clunky and poor technique. Sorry I don't know how to phrase the question better.
I am trying to eliminate all rows in excel that have he following features:
First column is an integer
Second column begins with an integer
Third column is empty
The code I have written appears to run indefinitely. CAS.MULT is the name of my dataframe.
for (i in 1:nrow(CAS.MULT)) {
testInteger <- function(x) {
test <- all.equal(x, as.integer(x), check.attributes = FALSE)
if (test == TRUE) {
return (TRUE)
}
else {
return (FALSE)
}
}
if (testInteger(as.integer(CAS.MULT[i,1])) == TRUE) {
if (testInteger(as.integer(substring(CAS.MULT[i,2],1,1))) == TRUE) {
if (CAS.MULT[i,3] == '') {
CAS.MULT <- data.frame(CAS.MULT[-i,])
}
}
}
}
You should be very wary of deleting rows within a for loop, if often leads to undesired behavior. There are a number of ways you could handle this. For instance, you can flag the rows for deletion and then delete them after.
Another thing I noticed is that you are converting your columns to integers before passing them to your function to test if they are integers, so you will be incorrectly returning true for all values passed to the function.
Maybe something like this would work (without a reproducible example it's hard to say if it will work or not):
toDelete <- numeric(0)
for (i in 1:nrow(CAS.MULT)) {
testInteger <- function(x) {
test <- all.equal(x, as.integer(x), check.attributes = FALSE)
if (test == TRUE) {
return (TRUE)
}
else {
return (FALSE)
}
}
if (testInteger(CAS.MULT[i,1]) == TRUE) {
if (testInteger(substring(CAS.MULT[i,2],1,1)) == TRUE) {
if (CAS.MULT[i,3] == '') {
toDelete <- c(toDelete, i)
}
}
}
}
CAS.MULT <- CAS.MULT[-1*toDelete,]
Hard to be sure without testing my code on your data, but this might work. Instead of a loop, the code below uses logical indexing based on the conditions you specified in your question. This is vectorized (meaning it operates on the entire data frame at once, rather than by row) and is much faster than looping row by row:
CAS.MULT.screened = CAS.MULT[!(CAS.MULT[,1] %% 1 == 0 |
as.numeric(substring(CAS.MULT[,2],1,1)) %% 1 == 0 |
CAS.MULT[,3] == ""), ]
For more on checking whether a value is an integer, see this SO question.
One other thing: Just for future reference, for efficiency you should define your function outside the loop, rather than recreating the function every time through the loop.