im new to R and was wondering if there is a way to assign names to columns in a matrix without using the colnames() function
#creating two vectors
player <- c(rep('dark',5),rep('light',5))
piece <-c('king','queen','pawn','pawn','knight','bishop','king','rook','pawn','pawn')
#creating a matrix
matrix2 <- c(player, piece)
dim(matrix2) <- c(10, 2)
#this would work perfectly but i was looking for an alternate method which doesn't uses
#colnames() function
colnames(matrix2) <- c('player','piece')
I also know that using cbind() would give me a matrix with column names as those of the two vectors
matrix2<-cbind(player,piece)
But I don't want to create my matrix with the cbind() function. I wanted to know if there is a way to name the colunmns of the matrix other than using the colnames() function after creating the matrix like I have created above.
Difficult to answer. Do you mean like this?
dimnames(matrix2) <- list(c(1:10), c("player", "piece"))
EDIT, without "naming" row_names (see comments, #akrun mentioned that earlier):
dimnames(matrix2) <- list(NULL, c("player", "piece"))
Related
I have a matrix (11x42) and I would like to apply a function for each column one by one and put the result back in a new 11x42 matrix with a new name and modified column names.
I am not used to loops so I am a bit struggling. Here is what I have so far, but not working.
for (i in 1:ncol(matrix))
{
res[[i]] <-residuals(lm(matrix[,i]~HW))
}
I would like to also use the function paste0("new_", i) to change the names of each column.
Here I was trying to create 42 vectors (res1 to res 42) that I would cbind into a new matrix. But it's not working. And I am pretty sure that could be done within the loop as well.
Thanks in advance!
Since its a matrix you should use apply with margin 2, i.e.
new_mat <- apply(your_mat, 2, function(i) residuals(lm(i~HW)))
colnames(new_mat) <- paste0('new_', colnames(your_mat))
I have a problem with cleaning up my code. I understand I could type this all out but we don't want that obviously.
I have only dataframes in my global environment. They are all "data.frame".
I want to check the dimensions of all of them and put that in a tibble. I managed that somehow. I also would like to change their colnames() tolower() which works easy if I just type the name of the data.frame, but there's more than 2 and I want it done automatically. Then I also want to mutate all data.frames in the same way.
Small example of my code:
library(tidyverse)
x <- data.frame(letters[1:2]) #To create the data
y <- data.frame(letters[3:4])
dfs <- as.list(ls()) #I take whatever is in my environment
I managed below to get a tibble of the dimensions:
z <- as_tibble(lapply(seq_along(dfs),
function(j) dim(get(dfs[[j]]))), .name_repair = "unique")
colnames(z) <- dfs
Now for the colnames of all the data.frames stored in my list I basically want to perform this code:
colnames(dfs[[1]]) <- tolower(colnames(dfs[[1]])
but that returns NULL as I found out earlier. So I used get() in there to make it work for the dimensions. But if I use get() to assign colnames it says it can't find function "get<-".
Since all colnames for all dataframes are the same (just different nrows()) I could save the lowercase colnames as value and use that, but that doesn't take away that it cant find the get<- function.
names <- tolower(colnames(x))
sapply(seq_along(dfs),
function(j) colnames(get(dfs[[j]])) <- names)
*Error in colnames(get(dfs[[j]])) <- names :
could not find function "get<-"*
as for the mutating part I tried a for loop:
for(i in seq_along(dfs)){
get(dfs[[i]]) <- get(dfs[[i]]) %>% mutate(cd = ab)
}
But it's the same issue.
Could anyone help clearing this problem for me? (and if a cleaner code for the dimensions is available that would be highly appreciated)
I am just trying to up my coding skills. I would have been long done if I just typed it all out but that defeats the purpose.
Thanks!
-JK
Using base R
lapply(dfs, function(x) transform(setNames(x, tolower(names(x))), X = c('a', 'b')))
I've finally lost my habit of loops in R. Basically usually calculating new columns, and then doing calculations and aggregations on these new columns.
But I have a question regarding cbind which I use for adding columns.
Is there a better way than using bind for things like this?
Naming this new column always is done by me in this tedious way... Anything cleverer/simpler out there?
library(quantmod)
getSymbols("^GSPC")
GSPC <- cbind(GSPC, lag(Cl(GSPC), k=1)) #Doing some new column calculation
names(GSPC)[length(GSPC[1,])] <- "Laged_1_Cl" #Naming this new column
GSPC <- cbind(GSPC, lag(Cl(GSPC), k=2))
names(GSPC)[length(GSPC[1,])] <- "Laged_2_Cl"
tail(GSPC)
** EDITED **
Roman Luštrik added a great solution in comments below.
GSPC$Laged_3_Cl <- lag(Cl(GSPC), k=3)
tail(GSPC)
One way of adding new variables to a data.frame is through the $ operator. Help page (?"$") shows common usage in the form of
x$i <- value
Where i is the new variable name and value are its associated values.
You can name the new column on the left side of the assignment like so:
exdat <- data.frame(lets = LETTERS[1:10],
nums = 1:10)
exdat$combo <- paste0(exdat$lets, exdat$nums)
I would like to build a function that adds many columns of random variables or other function to a a dataframe. Here I am trying to append it to map data.
library(plyr)
add <- function(name, df){
new.df = mutate(df, name = runif(length(df[,1])))
new.df
}
The function works to add a column of data...
add("e", iris)
iris2<- add("f", iris)
The apply does not work...
I am trying to add 26 columns from the list of letters so that df$a, df$b, df$c are all random vectors.
new <- lapply(letters, add, df = tx)
What is the most efficient way to columns from a list of col names?
I would like to later loop through all of the column names in another function.
It's not very clear to me, what you want to achieve. This adds multiple columns of random numbers to a data.frame:
cbind(iris,
matrix(runif(nrow(iris)*5), ncol=5))
I don't see a reason to use an *apply function.
I am a beginner to R programming and am trying to add one extra column to a matrix having 50 columns. This new column would be the avg of first 10 values in that row.
randomMatrix <- generateMatrix(1,5000,100,50)
randomMatrix51 <- matrix(nrow=100, ncol=1)
for(ctr in 1:ncol(randomMatrix)){
randomMatrix51.mat[1,ctr] <- sum(randomMatrix [ctr, 1:10])/10
}
This gives the below error
Error in randomMatrix51.mat[1, ctr] <- sum(randomMatrix[ctr, 1:10])/10 :incorrect
number of subscripts on matrix
I tried this
cbind(randomMatrix,sum(randomMatrix [ctr, 1:10])/10)
But it only works for one row, if I use this cbind in the loop all the old values are over written.
How do I add the average of first 10 values in the new column. Is there a better way to do this other than looping over rows ?
Bam!
a <- matrix(1:5000, nrow=100)
a <- cbind(a,apply(a[,1:10],1,mean))
On big datasets it is however faster (and arguably simpler) to use:
cbind(a, rowMeans(a[,1:10]) )
Methinks you are over thinking this.
a <- matrix(1:5000, nrow=100)
a <- transform(a, first10ave = colMeans(a[1:10,]))