Cannot create an empty vector and append new elements in R - r

I am just beginning to learn R and am having an issue that is leaving me fairly confused. My goal is to create an empty vector and append elements to it. Seems easy enough, but solutions that I have seen on stackoverflow don't seem to be working.
To wit,
> a <- numeric()
> append(a,1)
[1] 1
> a
numeric(0)
I can't quite figure out what I'm doing wrong. Anyone want to help a newbie?

append does something that is somewhat different from what you are thinking. See ?append.
In particular, note that append does not modify its argument. It returns the result.
You want the function c:
> a <- numeric()
> a <- c(a, 1)
> a
[1] 1

Your a vector is not being passed by reference, so when it is modified you have to store it back into a. You cannot access a and expect it to be updated.
You just need to assign the return value to your vector, just as Matt did:
> a <- numeric()
> a <- append(a, 1)
> a
[1] 1
Matt is right that c() is preferable (fewer keystrokes and more versatile) though your use of append() is fine.

Related

Saving R loop output into e.g. csv file

I am aware that this probably trivial but I can not solve it. And I have edited the original question a bit as I realized it was not very logical. See the code below:
u1 <- rnorm(30)
usq <- 0
for(i in 1:5)
{
usq[i] <- u1[i]*u1[i]
print(usq[i])
}
The output is (your might be different in terms of numbers):
[1] 0.3501974
[1] 0.01937814
[1] 0.4053783
[1] 0.0005323552
[1] 1.459631
All I want to do is to save this output as e.g. CSV file with one or two columns. I happy to be pointed out to any spot where this question was answered. I could not for the life of me find it... I have tried:
write.csv(matrix(1:5, ncol=1), "Results.csv")
I'm assuming the numbers are stand-ins for something a lot more complex - for loops in R are generally avoided - and it's rare that there isn't a better options somewhere.
To answer your question though, you need (as Gregor pointed out) write.csv. The one addition I would make is that the first time you call it, you need to make a new file.
write.csv(output_as_dataframe_or_matrix, file = "path_to_file.csv")
after that, you need to tell it not to overwrite what you had before:
write.csv(output_as_dataframe_or_matrix, file = "path_to_file.csv", append = TRUE)
Here's how you can achieve this (note that I'm removing the for loops. R will perform many operations on each element of a vector, and its much more efficient when you have it work this way.
u1 <- rnorm(30
usq <- u1^2 # or u1 * u1
print(usq)
write.csv(usq, "Results.csv")
This was probably not the most eloquently written question (my apologies for that) but the answer to it should be that the "empty container" has to be created first and then filled with numbers from the loop calculations. To solve my issue from above the following code did the job:
output<-matrix(0,5,1)
output<-as.data.frame(output)
u1 <- rnorm(30)
usq <- 0
for(i in 1:5)
{
usq[i] <- u1[i]*u1[i]
print(usq[i])
output$V1[i]<-usq[i]
}
write.csv(output, "Results.csv")

Add element in a vector while looping in R

I have a problem to solve in R language but I may need to add element in a loop while I am looping into it with a for, but the loop does not go through the new values.
I made a simple loop to explain the type of problem I have.
Here is the code:
c=c(1,2)
for(i in c){
c=c(c,i+2)
print(i)
}
And the result:
[1] 1
[1] 2
I would like this result:
[1] 1
[1] 2
[1] 3
[1] 4
It continues until I reach a condition.
Can someone tell me wether it is possible or not with an other way?
Thank you,
Robin
You could use a while loop instead:
test <- c(1,2)
n <- 1
while(n <= length(test)){
if(n == 5){
print(test)
break
}
print(test[n])
test <- c(test, n+2)
n <- n + 1
}
Note that in this case, the loop will keep on printing forever, so you should add some other condition to stop the loop at some point (here I quit it at 5).
Sidenote: You use c as a name for c(1,2). That's generally a bad idea, because c is reserved for defining vectors in R. It's always a good idea to avoid using names that are already used for other things by R itself.

R: Result vector is not showing up in For Loop

OK, so I am new to R, but I've had some pretty good success so far - I am running a statistical test between corresponding rows of two dataframes (well, one is just a string of values since it has just one column). I wish to use the following For-Loop:
zvalues = NULL
zvalues = numeric(0)
for(i in seq(nrow(geneexpx))){
zvalues[i] <- try(unname((geneexpx[i]-rowMeans(geneexpy[i,])) / rowSds(geneexpy[i,])))
}
The problem is, the resultant zvalues numeric is empty. I have no idea why. I can run the same function for a single row and it works fine. For instance:
s = unname(geneexpx[4]-rowMeans(geneexpy[4,])) / rowSds(geneexpy[4,])
s
[1] -2.431277e+156
Please let me know if you have any ideas as to what might be the problem.
EDIT:
head of geneexpx:
c(1.501400411, -0.818584726, -0.455614921, -0.138022494, -1.213938495, -0.536465133)
geneexpy is very large, but each column is similar to geneexpx above.
You have a couple things going on here. First, you need to define zvalues as a vector. Second, rowMeans and rowSds are operations on matrices, not vectors. By selecting greneecxpy[i, ] you are selecting the ith row of the matrix, which will be a vector.
You did not provide geneexpy so I made one up:
zvalues = rep(NA, length(geneexpx))
geneexpy <- matrix(runif(60), nrow = 6)
for(i in seq_along(geneexpx)){
zvalues[i] <- (geneexpx[i] - mean(geneexpy[i,])) / sd(geneexpy[i,])
}
> zvalues
[1] 3.772994 -4.283168 -2.812811 -2.074548 -5.649359 -4.323920

restoring original order of a vector/matrix in r

so i had a vector
> A<-c(19:30,1:5,6,100:80)
then i used
> A<-sort(A,index.return=T)
> valueA<-A$x
> indexA<-A$ix
to sort the vector and get a vector stating the values. i then performed some arithmetic on valueA that required it be sorted first and now i want to put the new values in the order that A was originally in (which is saved in the vector indexA).
is this a thing? sort of a "restore" or "un-sort" or whatever? i've tried looking around and it seems there are things that are close, but either not right or i'm not understanding.
thanks.
You want the base function order.
ord <- order(A)
A <- A[ord] #same as sort(A)
#do stuff, then revert
A <- A[order(ord)]

Assigning output of a function to two variables in R [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
function with multiple outputs
This seems like an easy question, but I can't figure it out and I haven't had luck in the R manuals I've looked at. I want to find dim(x), but I want to assign dim(x)[1] to a and dim(x)[2] to b in a single line.
I've tried [a b] <- dim(x) and c(a, b) <- dim(x), but neither has worked. Is there a one-line way to do this? It seems like a very basic thing that should be easy to handle.
This may not be as simple of a solution as you had wanted, but this gets the job done. It's also a very handy tool in the future, should you need to assign multiple variables at once (and you don't know how many values you have).
Output <- SomeFunction(x)
VariablesList <- letters[1:length(Output)]
for (i in seq(1, length(Output), by = 1)) {
assign(VariablesList[i], Output[i])
}
Loops aren't the most efficient things in R, but I've used this multiple times. I personally find it especially useful when gathering information from a folder with an unknown number of entries.
EDIT: And in this case, Output could be any length (as long as VariablesList is longer).
EDIT #2: Changed up the VariablesList vector to allow for more values, as Liz suggested.
You can also write your own function that will always make a global a and b. But this isn't advisable:
mydim <- function(x) {
out <- dim(x)
a <<- out[1]
b <<- out[2]
}
The "R" way to do this is to output the results as a list or vector just like the built in function does and access them as needed:
out <- dim(x)
out[1]
out[2]
R has excellent list and vector comprehension that many other languages lack and thus doesn't have this multiple assignment feature. Instead it has a rich set of functions to reach into complex data structures without looping constructs.
Doesn't look like there is a way to do this. Really the only way to deal with it is to add a couple of extra lines:
temp <- dim(x)
a <- temp[1]
b <- temp[2]
It depends what is in a and b. If they are just numbers try to return a vector like this:
dim <- function(x,y)
return(c(x,y))
dim(1,2)[1]
# [1] 1
dim(1,2)[2]
# [1] 2
If a and b are something else, you might want to return a list
dim <- function(x,y)
return(list(item1=x:y,item2=(2*x):(2*y)))
dim(1,2)[[1]]
[1] 1 2
dim(1,2)[[2]]
[1] 2 3 4
EDIT:
try this: x <- c(1,2); names(x) <- c("a","b")

Resources