I would like to create a vector from each column of mtcars data frame. I need two solutions. First one should be done in loop and if it's possible the other one without a loop.
The desired output should be like that:
vec_1 <- mtcars[,1]
vec_2 <- mtcars[,2]
etc...
I tried to create a loop but I failed. Can you tell me what is wrong with that loop ?
vec <- c()
for (i in 1:2){
assign(paste("vec",i,sep="_" <- mtcars[,i][!is.na(mtcars[,i])]
}
I need to remove possible NAs from my data that's why I put it in the example.
Your loop is missing a few brackets and you should assign the vector to the global environment of your R session like so:
for (i in 1:2) {
assign(sprintf("vec_%d", i), mtcars[!is.na(mtcars[[i]]), i], envir = .GlobalEnv)
}
It is not possible to get the desired result without a loop.
Related
I am trying to take my data frame that has a list of player id numbers and find their name, using this function. Right now my code will simply print separate tibbles of each result, but I want it to combine those results into a data frame. I tried using rbind, but it doesn't work.
for(x in dataframe...)
print(function I am using to find name)
Use sapply which is more efficient than looping :
results <- data.frame(name = sapply(dataframe[,'playerid'], FUN = function(id) baseballr::playername_lookup(id)))
You can initialise a results data frame like this
results <- data.frame()
You can then add the results in each loop using rbind combining the previous version with the new results. In the first iteration of the loop you add your first results to an empty data frame. So combined
results <- data.frame()
for(x in dataframe$playerid){
results <- rbind(results, baseballr::playername_lookup(x))
}
The problem in you code was that you simply printed the results without saving them anywhere.
As mentioned in the comment below, the better way to do this, once your data set becomes very large, is to create a list an later combine that to a data.frame.
results <- list()
for(i in seq_len(nrow(dataframe))){
results[[i]] <- baseballr::playername_lookup(dataframe$playerid[i])
}
final_results <- do.call(rbind, results)
I have a 18-by-48 matrix.
Is there a way to save each of the 18 rows automatically in a separate variable (e.g., from r1 to r18) ?
I'd definitely advise against splitting a data.frame or matrix into its constituent rows. If i absolutely had to split the rows up, I'd put them in a list then operate from there.
If you desperately had to split it up, you could do something like this:
toy <- matrix(1:(18*48),18,48)
variables <- list()
for(i in 1:nrow(toy)){
variables[[paste0("variable", i)]] <- toy[i,]
}
list2env(variables, envir = .GlobalEnv)
I'd be inclined to stop after the for loop and avoid the list2env. But I think this should give you your result.
I believe you can select a row r from your dataframe d by indexing without a column specified:
var <- d[r,]
Thus you can extract all of the rows into a variable by using
var <- d[1:length(d),]
Where var[1] is the first row, var[2] the second. Etc.. not sure if this is exactly what you are looking for. Why would you want 18 different variables for each row?
result <- data.frame(t(mat))
colnames(result) <- paste("r", 1:18, sep="")
attach(result)
your matrix is mat
I want to create a new dataframe and keep adding variables in R with in a for loop. Here is a pseudo code on what I want:
X <- 100
For(i in 1:X)
{
#do some processing and store it a variable named "temp_var"
temp_var[,i] <- z
#make it as a dataframe and keep adding the new variables until the loop completes
}
After completion of the above loop the vector "temp_var" by itself should be a dataframe containing 100 variables.
I would avoid using for loops as much as possible in R. If you know your columns before hand, lapply is something you want to use.
However, if this is constraint by your program, you can do something like this:
X <- 100
tmp_list <- list()
for (i in 1:X) {
tmp_list[[i]] <- your_input_column
}
data <- data.frame(tmp_list)
names(data) <- paste0("col", 1:X)
i'm a bit new to R and this site has been an amazing help to me in answering a lot of questions. However, I’ve come across a recent problem and have exhausted all options to find a solution on my own and am in need of some help.
I am trying to write a code where I create multiple data frames (or matrices) INSIDE the loop and loop it 5000 times. On each loop I would like the variable to change so I can retrieve the data for each loop at a later point.
Also, I would like to be able to repeat this method for other data frames and in creating these new data frames, it draws upon other data frames based on the iteration it is on.
I have tried to find a solution to this and it seems that it could be either the for loop or apply function, but I am not sure as to how I could execute it. As an example of what I would like to see:
for (i in 1:10) {
df.a[i] <- data.frame (…information...)
df.b[i] <- data.frame (...information...)
df.c[i] <- data.frame (new.col.A=df.a[i]$column1, new.col.B=df.b[i]$column2)
}
Then, after having run the loop, if I were to write df.c3 I would find the data frame created in the loop on the third iteration which has data from iteration 3 in df.a and df.b.
The ‘closest’ I have come to getting what I thought I needed was by doing this:
df.a = seq (1, 10, by=1)
df.b = seq (1,10, by=1)
df.c = seq (1,10, by=1)
for (i in 1:10) {
df.a[[i]] <- data.frame (...information)
...
}
But this typically results in an error of: "number of items to replace is not a multiple of replacement length".
So i'm not sure what else i could do and really hope someone is able to help out.
Create objects df.x as empty lists:
df.a <- list()
df.b <- list()
df.c <- list()
Then access (and write to) individual dataframes using double square backets:
for (i in 1:10) {
df.a[[i]] <- data.frame(...)
df.b[[i]] <- data.frame(...)
df.c[[i]] <- data.frame(new.col.A=df.a[[i]]$column1, new.col.B=df.b[[i]]$column2)
}
I have multiple data frames named y1 to y13 - one column each. They all have a column name that I would like to change to "Date.Code". I've tried the following in a for loop:
for(i in 1:13){
colnames(get(paste("y", i, sep=""))) <- c("Date.Code")
}
That didn't work.
I also tried:
for(i in 1:13){
assign(("Date.Code"), colnames(get(paste("y", i, sep=""))))
}
Also with no luck.
Any suggestions?
Thanks,
E
The difficulty here is that you cannot use get with an assignment operator directly
eg, get(nm) <- value will not work. You can use assign, as you're trying, but in a slightly different fashion.
assuming cn is the column number whose name you would like to change
for(i in 1:13){
nm <- paste0("y", i)
tmp <- get(nm)
colnames(tmp)[cn] <- c("Date.Code")
assign(nm, tmp)
}
That being said, a cleaner way of approaching this would be to collect all of your DF's into a single list, then you can easily use lapply to operate on them. For Example:
# collect all of your data.frames into a single list.
df.list <- lapply(seq(13), function(i) get(paste0("y", i)))
# now you can easily change column names. Note the `x` at the end of the function which serves
# as a return of the value. It then gets assigned back to an object `df.list`
df.list <-
lapply(df.list, function(x) {colnames(x)[cn] <- "Date.Code"; x})
Lastly, search these boards for [r] data.table and you will see many options for changing values by reference and setting attributes more directly.
Here one liner solution:
list2env(lapply(mget(ls(pattern='y[0-9]+')),
function(x) setNames(x,"Date.Code")),.GlobalEnv)
Of course it is better to keep all your variable in the same list.