R - add same element to vector without use for loop - r

I'm pretty new in R, I only know its foundamental concepts.
I have the v vector:
v<-c(1,2,3,4)
and I would like to append to v four NA values, obtaining:
v(1,2,3,4,NA,NA,NA,NA)
T o solve this I can use a for loop:
for(i in 1:4){
v<-append(v, NA)
}
My question is: are there clever and/or faster R solutions I could use?

From the above comments we had found some useful answers where every new OP can view in aswer window rather than comment sections, thanks OP for your valuable answers
v <- c(v, rep(NA, 4)) # joel.wilson
length(v)<-length(v)+4 # Nicola
'length<-'(v, 8) # akrun
Please note:
in general the Joel.Wilson's option is the good one 'cause can be used to append several times a specific value (numeric, character, boolean, etc.), while other two solutions only NA values as they play on the length property.

Related

How can manipulate different variables with similar names in a for loop in r? [duplicate]

Similar questions have been raised for other languages: C, sql, java, etc.
But I'm trying to do this in R.
I have:
ret_series <- c(1, 2, 3)
x <- "ret_series"
How do I get (1, 2, 3) by calling some function / manipulation on x, without direct mentioning of ret_series?
You provided the answer in your question. Try get.
> get(x)
[1] 1 2 3
For a one off use, the get function works (as has been mentioned), but it does not scale well to larger projects. it is better to store you data in lists or environments, then use [[ to access the individual elements:
mydata <- list( ret_series=c(1,2,3) )
x <- 'ret_series'
mydata[[x]]
What's wrong with either of the following?
eval(as.name(x))
eval(as.symbol(x))
Note that some of the examples above wouldn't work for a data.frame.
For instance, given
x <- data.frame(a=seq(1,5))
get("x$a") would not give you x$a.

Dplyr::filter works on data frame but not on vector, why is this?

I have used dplyr:filter on a data frame to get all the numbers not divisible by 3 and 2, but this function did not work on a vector. I am curious as to why this is so?
Here is my code:
vec<-vector()
for (i in 1:1260){
if (i %% 2 !=0){
vec<-c(vec,i)
}
}
vec<-data.frame(vec)
vec%>%filter(vec%%3!=0)
This should work:
vec<-vector()
for (i in 1:1260){
if (i %% 2 !=0){
vec<-c(vec,i)
}
}
vec<-data.frame(vec)
answer <- vec%>%filter(vec%%3!=0)
real_answer <- answer$vec
The problem is that filter is meant to work with dataframes
Looking at the documentation here it seems like only the use with a tibble/tbl is correct and you are lucky that your data.frame works: https://www.rdocumentation.org/packages/dplyr/versions/0.7.8/topics/filter
This seems to be part of a general understanding that tidy data is data in data.frames.
In R data are often used in vectors and if a and b are vectors of data you can just plot them using
plot(a, b)
where there is an implicit connection of the value of a[n] and the value of b[n] being connected via a common n. However, there is always a risk of that implicit connection being disturbed when changing a or b alone. There is less risk if the connection is made explicit within a data.frame or a tibble where values in the same row belong together.
If, e. g. you do na.omit(a) there is no telling which a value belongs to which b value, whereas a na.omit(data.frame(a, b)) is save in this regard.
Without using data.frame, you can try
vec[vec%%3!=0]
or
subset(vec,vec%%3!=0)

Removing NA from list of lists in R in function

I have a function that takes a nested list (or list of lists) of integers as the input and assigns values of NA randomly according to some probability, p1. I would like to extend this function to remove the NAs from the list.
I know removing NAs is a common question on the internet and have reviewed the the questions on Stack Overflow and elsewhere, but none of the solutions work. In general, the questions posed do not refer to an actual list of lists.
I have tried:
#Example data
d<-list(1,3,c(0,NA,0),c(0,0))
e<-list(1,6,c(0,3,NA,0,NA,0),c(0,NA,0,1,0,0),1,NA,c(0,0))
f<-list(1,0)
L.miss<-list(d,e,f)
#Tests
test1<-lapply(L.miss,function(x) x[!is.na(x)]) #Doesnt work
test2<-lapply(L.miss,Filter,f=Negate(is.na)) #Doesnt work
test3<-lapply(L.miss,na.omit) #Doesnt work
Below is the function I am using to assign the NA values (also, don't laugh if its clunky, I am likely not near as experienced in coding as you!). I am also adding code that would generate a sample list of lists of length three, with various lengths of lists nested, that are similar to my actual data input (though length of 2000).
imperfect.passive<-function(z,p1){
z.imp<-z
obs.surv<-integer()
for (i in 1:length(z)){
for (j in 1:length(z[[i]])){
for (k in 1:length(z[[i]][[j]])){
for (l in 1:length(z[[i]][[j]][[k]])){
obs.surv[l]<-rbinom(1,1,p1)
if (obs.surv[l]==0){
z.imp[[i]][[j]][[k]]<-NA
}
}
#######################################
##'#TODO -> Remove NA values from list
#######################################
}
}
}
return(z.imp)
}
#####for small example
a<-list(1,3,c(0,2,0),c(0,0))
b<-list(1,6,c(0,3,2,0,1,0),c(0,0,0,1,0,0),1,2,c(0,0))
c<-list(1,0)
L.full<-list(a,b,c)
#assign NA with p=0.5
example<-imperfect.passive(L.full,0.5)
Any advice would be appreciated, and I apologize if this is answered elsewhere - I could not find it.
Use rapply:
rapply(L.miss, na.omit, how = "replace")
As an alternative to na.omit in the rapply function, which produces some extraneous information, I also found the following code to perform better for my purposes:
rapply(test2,function(x) x[!is.na(x)], how="replace")
Of course, either would work, just another option!

R: performing same task on multiple matrices

I have about 150 matrices, each with a name in the convention of "BID_xxx" (for example: BID_ABL, BID_BGA). I would like to split the first column of each of these matrices into two using substr. So, for example: BID_ABL[,5] = substr(BID_ABL[,1],1,10)
Would anyone be able to help me find a way of doing this without writing out the above line 150 times, once for each matrix?
Any help would be great!
Thanks
Mike
The functions get and assign are your friends here:
for (n in ls()[grep("^BID_",ls())]) {
x <- get(n)
x[,5] <- substr(x[,1],1,10)
assign(n, x)
}
Should do what you want.
Like this:
allnames<- ls(pat='BID_')
for(j in 1:length(allnames)) print(get(allnames[j])[1])
Where you'd replace "print" with your substring function.
Edit: Sam's answer is essentially the same. How you get the list of object names depends on what other stuff is in your environment.

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