Loops and filling empty vectors in R - r

I'm looking to fill in this empty vector:
empty_vec <- rep("", times=length(number_vec))
with sequential numbers from this loop:
for (numbers in number_vec) {
sqrt <- sqrt(numbers)
empty_vec[numbers] <- sqrt
}
where numbers_vec is c(16:49).
However, when I do this, the first positions (1-15) in my empty_vec are not filled?

You can address this in two ways:
First, you can create a counter, that will register which step of the loop you are, and use this as index to empty_vect, like this:
empty_vec <- rep("", times=length(number_vec))
counter=0
for (numbers in number_vec) {
counter=counter+1
sqrt<-sqrt(numbers)
empty_vec[counter]<-sqrt
}
Or you can just create an empty vector and concatenate each new value, like this:
empty_vec <- c()
for (numbers in number_vec) {
sqrt<-sqrt(numbers)
empty_vec <- c(empty_vec,sqrt)
}
The way you were doing, is like you started to fill your vector in 16th position, that's way you had error.

First you need to understand how for loop works
General express for for loop is
for(var in seq) expr
var = A syntactical name for a variable
seq = An expression evaluating to a vector (including a list and an expression) or to a pairlist or NULL. A factor value will be coerced to a character vector.
so note it , "seq" will be the value of the "var".
In your example , you wrote
for (numbers in number_vec)
where,
numbers = Name of the variable
number_vec = c(16:49)
So here , the initial value of "numbers" will be first value of "number_vec" which is 16.
in later step in loop, the expression
empty_vec[numbers]<-sqrt
where ,
empty_vec[numbers] indicate the 16th position of the empty_vec as initially numbers started with value 16
As you start with 16th position , the previous 15 position remain empty.
Possible solution of your problem :
number_vec = c(16:49)
empty_vec <- rep("", times=length(number_vec))
for (numbers in seq_along(number_vec)) {
sqrt<-sqrt(number_vec[numbers])
empty_vec[numbers]<-sqrt
}

Related

R - How do you populate a vector inside a function?

I have a complex function. The function works. Inside, there is a vector called csvcols, which reads a csv, and creates a list of columns in my csv that have a quality I am looking for.
After my function is complete, csvcols is NULL, even though when I include print(csvcols) within the function, it returns columns, e.g. (1, 3, 5, 6, 7).
How can I get a list of all of the columns after I have looped through my variable, like for(xx in loop){SumofGeneration}?
SumofGeneration <- function(xx) {
csvcols = c()
for(i in 1:length(xx)) {
func2(xx[i])
if( func2(xx[i]) == T){
csvcols <- c(csvcols, which(colnames(filename) %in% xx[i]))
}
}
xxgeneration <- rowSums(filename[,csvcols])
}
#Generates list of relevant cols (csvcols vector) in file (filename)
#Sums values in those cols and returns xxgeneration
loop <- c( 14 strings here)
For (xx in loop){
SumofGeneration(xx)}
I have tried saving my csvcols as:
csvcols2 <- c(csvcols2, csvcols)
My loop runs SumofGeneration on 14 strings in my list (loop), and within the function generates values in csvcols, and then when the function ends I lose these values and csvcols = NULL.
csvcols2 always returns NULL. How can I stop losing my values?
I want my output to be a vector with all 14 csvcols values in one vector - csvcols2.

function with vector R - argument is of length zero

Wrote this function lockdown_func(beta.hat_func).
First thing is: I get an error "argument is of length zero".
Second thing is: when I compute it without the date indices, it doesn't change the value as it should, output vector contains same value for every indices.
date= c(seq(from=30, to=165))
beta.hat_func <- c(rep(x = beta.hat, times = 135))
beta.hat <- beta0[which.min(SSE)]
#implement function for modeling
lockdown_func <- function(beta.hat_func,l){
h=beta.hat_func
{
for(i in 1:length(h))
if(date[i]>60 | date[i]<110){
beta.hat_func[i]=beta.hat_func[i]*exp(-l*(date[i]-date[i-1]))
}else{
beta.hat_func[i]=beta.hat_func[i]
}
return(h)
}
}
lockdown_func(beta.hat_func,0.03)
A few comments:
did you mean to apply an AND rather than an OR to get date range between 60 and 110? This would be date[i]>60 && date[i]<110 (it's better to use the double-&& if you are computing a length-1 logical value)
because you didn't, i=1 satisfies the criterion, so date[i-1] will refer to date[0], which is a length-0 vector.
You might want something like:
l_dates <- date>60 & date<110 ## single-& here for vectorized operation
beta.hat_func[l_dates] <- beta.hat_func[l_dates]*exp(-l*diff(date)[l_dates])

Append a vector of values to key-value lists in R

I am looking to append values within a for-loop to a key-value list.
I have 2 lists containing dates and a for loop that checks for if each of the dates within the first list falls between a pair of dates from both lists. The outer loop takes care of constructing the lists and defining the intervals.
Here's the inner for-loop code:
for(j in 1:length(Dates)){
ifelse(Dates[j] %within% int,
Concurrent[[ key ]] <- append(case[i], case[j]),
No_Conc[[ key ]] <- append(case[i], case[j])
}
I think the important code lines here are the append statements. My values I am looking for are being replaces by last 2 values. However, I would like to be able append values to the corresponding key in the list.
In python, this is how it would be done.
list1 = [123, 234, 456]
d = {'a': [], 'b': []}
for(i in range(list1){
d['a'].append(list1[i])
}
I think I understand what you are asking. I'm sure better answers will come along, but to give you something to work with sooner, try something like the following. It may not work because I don't have data to work with.
for(j in 1:length(Dates)){
ifelse(Dates[j] %within% int,
Concurrent[[ key ]] <- (case[i], case[j]),
No_Conc[[ key ]] <- (case[i], case[j])
if (i==1 & j==1)
ret <- Concurrent[[key]]
ret2<- No_Conc[[key]]
else
ret <- data.frame(rbind(ret,Concurrent[[key]])
ret2 <- data.frame(rbind(ret2, No_Conc[[key]])
}

use of double brackets unclear

I'm new to R. Reading Book Of R by Tilman Davies. An example is provided for how to use an externally defined helper function which incidentally utilizes double square brackets [[]]. Please explain what helper.call[[1]] and helper.call[[2]] are doing and use of double brackets here.
multiples_helper_ext <- function(x=foo,matrix.flags,mat=diag(2){
indexes <- which(matrix.flags)
counter <- 0
result <- list()
for(i in indexes){
temp <- x[[i]]
if(ncol(temp)==nrow(mat)){
counter <- counter+1
result[[counter]] <- temp%*%mat
}
}
return(list(result,counter))
}
multiples4 <- function(x,mat=diag(2),str1="no valid matrices",str2=str1){
matrix.flags <- sapply(x,FUN=is.matrix)
if(!any(matrix.flags)){
return(str1)
}
helper.call <- multiples_helper_ext(x,matrix.flags,mat=diag(2)
result <- helper.call[[1]] #I dont understand this use of double bracket
counter <- helper.call[[2]] #and here either
if(counter==0){
return(str2)
} else {
return(result)
}
}
foo <- list(matrix(1:4,2,2),"not a matrix","definitely not a matrix",matrix(1:8,2,4),matrix(1:8,4,2))
In R there are two basic types of objects: lists and vectors. The items of lists can be other objects, the items of of vectors are usually numbers, strings, etc.
To access items in a list, you use the double bracket [[]]. This gives back the object at that place of the list.
So
x <- 1:10
x is now a vector of integers
L <- list( x, x, "hello" )
L is a list whose first item is the vector x, its second item is the vector x, and its third item is the string "hello".
L[[2]]
This give back a vector, 1:10, which is stored in the 2nd place in L.
L[2]
This is a bit confusing, but this gives back a list whose only item is 1:10, i.e. it only contains L[[2]].
In R, when you want to return multiple values, you usually do this with a list. So, you might end you function with
f <- function() {
return( list( result1="hello", result2=1:10) )
}
x = f()
Now you can access the two results with
print( x[["result1"]] )
print( x[["result2"]] )
You can also access items of a list with ''$, so instead you can write
print( x$result1 )
print( x$result2 )
The syntax [[]] is used for list in python. Your helper.call is a list (of result and counter), so helper.cal[[1]] returns the first element of this list (result).
Have a look here: Understanding list indexing and bracket conventions in R

Finding the position of a character within a string

I am trying to find the equivalent of the ANYALPHA SAS function in R. This function searches a character string for an alphabetic character, and returns the first position at which at which the character is found.
Example: looking at the following string '123456789A', the ANYALPHA function would return 10 since first alphabetic character is at position 10 in the string. I would like to replicate this function in R but have not been able to figure it out. I need to search for any alphabetic character regardless of case (i.e. [:alpha:])
Thanks for any help you can offer!
Here's an anyalpha function. I added a few extra features. You can specify the maximum amount of matches you want in the n argument, it defaults to 1. You can also specify if you want the position or the value itself with value=TRUE:
anyalpha <- function(txt, n=1, value=FALSE) {
txt <- as.character(txt)
indx <- gregexpr("[[:alpha:]]", txt)[[1]]
ret <- indx[1:(min(n, length(indx)))]
if(value) {
mapply(function(x,y) substr(txt, x, y), ret, ret)
} else {ret}
}
#test
x <- '123A56789BC'
anyalpha(x)
#[1] 4
anyalpha(x, 2)
#[1] 4 10
anyalpha(x, 2, value=TRUE)
#[1] "C" "A"

Resources