how to print product of vector in R - r

So this is my current code:
vec_prod <- function(x){
out <- 1
for(i in 1:length(x)){
out <- out*x[i]
}
out
}
however, i want to print out the product of vector [2,3,5]
but it does not accept those values. I can only input (1:3) or (1:4)
I'm new to R programming so any help is appreciated. I do not want to use any other functions.

Issue wasn't in function code, but probably in the way user called it. I propose my cleaner version. But you should really just use prod.
vec_prod <- function(x){
out <- 1
for(i in x){
out <- out*i
}
out
}
vex_prod(c(4,5,6))

Related

Using for loop to append vectors of variable length

I am trying to create a vector or list of values based on the output of a function performed on individual elements of a column.
library(hpoPlot)
xyz_hpo <- c("HP:0003698", "HP:0007082", "HP:0006956")
getallancs <- function(hpo_col) {
for (i in 1:length(hpo_col)) {
anc <- get.ancestors(hpo.terms, hpo_col[i])
output <- list()
output[[length(anc) + 1]] <- append(output, anc)
}
return(anc)
}
all_ancs <- getallancs(xyz_hpo)
get.ancestors outputs a character vector of variable length depending on each term. How can I loop through hpo_col adding the length of each ancs vector to the output vector?
Welcome to Stack Overflow :) Great job on providing a minimal reproducible example!
As mentioned in the comments, you need to move the output <- list() outside of your for loop, and return it after the loop. At present it is being reset for each iteration of the loop, which is not what you want. I also think you want to return a vector rather than a list, so I have changed the type of output.
Also, in your original question, you say that you want to return the length of each anc vector in the loop, so I have changed the function to output the length of each iteration, rather than the whole vector.
getallancs <- function(hpo_col) {
output <- numeric()
for (i in 1:length(hpo_col)) {
anc <- get.ancestors(hpo.terms, hpo_col[i])
output <- append(output, length(anc))
}
return(output)
}
If you are only doing this for a few cases, such as your example, this approach will be fine, however, this paradigm is typically quite slow in R and it's better to try and vectorise this style of calculation if possible. This is especially important if you are running this for a large number of elements where computation will take more than a few seconds.
For example, one way the function above could be vectorised is like so:
all_ancs <- sapply(xyz_hpo, function(x) length(get.ancestors(hpo.terms, x)))
If in fact you did mean to output the whole vector of anc, not just the lengths, the original function would look like this:
getallancs <- function(hpo_col) {
output <- character()
for (i in 1:length(hpo_col)) {
anc <- get.ancestors(hpo.terms, hpo_col[i])
output <- c(output, anc)
}
return(output)
}
Or a vectorised version could be
all_ancs <- unlist(lapply(xyz_hpo, function(x) get.ancestors(hpo.terms, x)))
Hope that helps. If it solves your problem, please mark this as the answer.

How to call specific outputs of the function as once

Suppose I have a function which returns me a list of output. How could I call a specific output at once? My original function is difficult and must return my output as a list. Sometimes I need to look at a special output (3 or 5 of them (out of 10). How can I do that very quickly using a shortcut code instead of repeating it several times to get one output each time?
For example,
x <- rnorm(1:5)
y <- rnorm(1:5)
myfun <- function(x,y){
mult <- sumf <- distfu <- list()
for(i in 1:5){
mult[[i]] <- x[[i]]*y[[i]]
sumf[[i]] <- x[[i]]+y[[i]]
distfu[[i]] <- x[[i]]-y[[i]]
}
out <- list()
out$mult <- mult
out$sumf <- sumf
out$distf <- distfu
return(out)
}
myres <- myfun(x,y)
How can I call myres$multand
myres$distf only at one time?
I tried this: myres$[c(1,3)] but it was wrong.
Please note that this example is simple, however, my function returns more than 10 outputs. So, if I need to only look at 5 of them, then I need to repeat this myfun$.. five times. I just would like to know if there is a way to call all the 5 outputs at once`.
To call a specific elements of a list you must do it like this:
myres[c(1,3)]
In your code there was a typo $ after myres
I hope this will help you.

R: Build custom cumsum function in sapply

I'm trying to build a more custom version of cumsum to use on a data.table, but I'm failing at the first step:
numbers <- data.table(num=1:10)
sum <- 0
cumFunct <- function(n) {
sum <<- sum+n
return(sum)
}
numbers[, cum:=sapply(num, cumFunct)]
While this works, it is very unclean. It also requires sum to be set to 0 before I run the function.
Now, how do I write this in a cleaner way? Essentially, how can I pass the intermediate result to the next iteration of cumFunct without using global variables?
Thanks very much!
One way to do this would be to use the datatable "numbers" within the function:
numbers <- data.table(num=1:10)
cumFunct <- function(n) {
sum <- sum(numbers[1:n])
return(sum)
}
numbers[, cum:=sapply(num, cumFunct)]
This is not the most efficient way, but depending on what you do in your custom code, one can improve it.
An answer that is also a question: is this a pattern that will work here?
complicated.wizardry <- function(a,b){
a+b
}
cumlist <- function(sofar, remaining, myfn){
if(length(remaining)==1)return(c(sofar, myfn(sofar[length(sofar)],remaining[1])))
return ( cumlist( c(sofar, myfn(sofar[length(sofar)],remaining[1])),remaining[2:length(remaining)],myfn))
}
cumlist(0,1:10,complicated.wizardry)

R - How can I calculate a matrix with a function?

i have a problem with following code in R. I want myfun() function to write some data into the my.res matrix. I can print the statement my.vec[i]/my.vec[i-j] easily.
my.vec <-c(1:10)
my.res <-matrix( ,10,2)
myfun <-function(j=2){
for(i in (j+1):10){
my.res[i,1] <-my.vec[i]/my.vec[i-j]
print(my.vec[i]/my.vec[i-j])
}
}
You have your print in the wrong location, also changed your input j=2 to simply j that can be assigned. As mentioned - you don't need a loop to do this - but seems like you are just trying to learn how to work with loops?
myfun <- function(j){
for(i in (j + 1):10){
my.res[i,1] <- my.vec[i]/my.vec[i-j]
}
print(my.res)
}
myfun(2)

usings a for loop to append to an empty object in r

this may seem like a novice question, but I'm struggling to understand why this doesn't work.
answer = c()
for(i in 1:8){
answer = c()
knn.pred <- knn(data.frame(train_week$Lag2), data.frame(test_week$Lag2), train_week$Direction, k=i)
test <- mean(knn.pred == test_week$Direction)
append(answer, test)
}
I want the results 1-8 in a vector called answer. it should loop through 8 times, so ideally a vector with 8 numbers would be my output. When I run the for loop, I only get the final answer, meaning it isn't appending. any help would be appreciated, sorry for the novice question, really trying to learn R.
First of all, please include a reproducible example in your question next time. See How to make a great R reproducible example?.
Second, you set answer to c() in the first line of your loop, so this happens in each iteration.
Third, append, just like almost all functions in R, does not modify its argument in place, but it returns a new object. So the correct code is:
answer = c()
for (i in 1:8){
knn.pred <- knn(data.frame(train_week$Lag2), data.frame(test_week$Lag2),
train_week$Direction, k = i)
test <- mean(knn.pred == test_week$Direction)
answer <- append(answer, test)
}
While this wasn't the question, I can't help noting that this is a very inefficient way of creating vectors and lists. It is an anti-pattern. If you know the length of the result vector, then allocate it, and set its elements. E.g
answer = numeric(8)
for (i in 1:8){
knn.pred <- knn(data.frame(train_week$Lag2), data.frame(test_week$Lag2),
train_week$Direction, k = i)
test <- mean(knn.pred == test_week$Direction)
answer[i] <- test
}
You are overwriting answer inside the for loop. Try removing that line. Also, append doesn't act on its arguments directly; it returns the modified vector. So you need to assign it.
answer <- c()
for(i in 1:8){
knn.pred <- knn(data.frame(train_week$Lag2), data.frame(test_week$Lag2), train_week$Direction, k=i)
test <- mean(knn.pred == test_week$Direction)
answer <- append(answer, test)
}

Resources