Both extract and create names for columns within a matrix - r

I have a matrix with columns denoting 30 different frequency windows and rows denoting dates. I would like to extract each column and assign a variable to each resulting vector and have the name of that variable be the name of that frequency window (which I have in center values, so I'd like to name each variable something like f100). What is the best way to write a loop to both extract and name each variable?
Thanks!

If you want to create 30 variables in the global environment from the columns of the matrix, you could use list2env or assign (I would probably keep it together in a matrix/dataframe or even in a list and do all the necessary operations rather than cluttering the global environment with lots of variables).
list2env(lapply(as.data.frame(mat), function(x) x), envir=.GlobalEnv)
# <environment: R_GlobalEnv>
f1
#[1] 37 38 12 34 26 21 30 6 27 29
data
set.seed(42)
mat <- matrix(sample(1:40, 30*10, replace=TRUE), ncol=30,
dimnames=list(NULL, paste0("f", 1:30)))

Related

I need to build new matrices by selecting alternate columns of the original matrix

I have a matrix where the first column is the ID of the samples, the columns 2 to 15 are the observed presences of 14 fish species, and the columns 16 to 29 are the predicted presences of the same 14 species.
I need to build 14 matrices (1 per species) with 3 columns each: first column = ID of the samples (e.g. column 1 of the original matrix), 2nd column = observed presence of the species, 3rd column = predicted presence of the species.
Lets say that A is the ID of my samples:
A<-c(1,2,3,4,5,6,7,8,9,10)
B are the observed values for my species
B<-replicate(14,rnorm(10))
C are the predicted values for my species
C<-replicate(14,rnorm(10))
So I have the matrix "data":
data<-cbind(A, B, C)
I want to do something like this
A1<-cbind(data[,1],data[,2],data[,16])
A2<-cbind(data[,1],data[,3],data[,17])
etc.. until having A1 to A14 matrices, one for each species. I suspect that I need to use the lapply function but I am lost. Can anyone help me?
Thanks!!
We can use lapply to create a list of matrices by looping through the sequence of columns
lst <- lapply(seq_len(ncol(B)), function(i) cbind(A, B= B[,i], C=C[,i]))
names(lst) <- paste0("A", seq_along(lst))
It is better to keep it in a list instead of creating multiple objects in the global environment. But, if we need it anyway
list2env(lst, .GlobalEnv)

How to compute all possible combinations of multiple vectors/matrices of different sizes and sum up columns simultaneously?

Assume I have three matrices...
A=matrix(c("a",1,2),nrow=1,ncol=3)
B=matrix(c("b","c",3,4,5,6),nrow=2,ncol=3)
C=matrix(c("d","e","f",7,8,9,10,11,12),nrow=3,ncol=3)
I want to find all possible combinations of column 1 (characters or names) while summing up columns 2 and 3. The result would be a single matrix with length equal to the total number of possible combinations, in this case 6. The result would look like the following matrix...
Result <- matrix(c("abd","abe","abf","acd","ace","acf",11,12,13,12,13,14,17,18,19,18,19,20),nrow=6,ncol=3)
I do not know how to add a table in to this question, otherwise I would show it more descriptively. Thank you in advance.
You are mixing character and numeric values in a matrix and this will coerce all elements to character. Much better to define your matrix as numeric and keep the character values as the row names:
A <- matrix(c(1,2),nrow=1,dimnames=list("a",NULL))
B <- matrix(c(3,4,5,6),nrow=2,dimnames=list(c("b","c"),NULL))
C <- matrix(c(7,8,9,10,11,12),nrow=3,dimnames=list(c("d","e","f"),NULL))
#put all the matrices in a list
mlist<-list(A,B,C)
Then we use some Map, Reduce and lapply magic:
res <- Reduce("+",Map(function(x,y) y[x,],
expand.grid(lapply(mlist,function(x) seq_len(nrow(x)))),
mlist))
Finally, we build the rownames
rownames(res)<-do.call(paste0,expand.grid(lapply(mlist,rownames)))
# [,1] [,2]
#abd 11 17
#acd 12 18
#abe 12 18
#ace 13 19
#abf 13 19
#acf 14 20

Assign data frame name to list elements using name vector

I have a data frame, 'mydata':
head(mydata)
ID MDC
000001 21A
000002 5
000003 8
...
I've split my data frame by one of it's column values, namely 'MDC'. This created a list, subdivided into further lists by the column value 'MDC':
mylist <- split(mydata, mydata$MDC, drop=TRUE)
summary(mylist)
Length Class Mode
0 75 data.frame list
1 75 data.frame list
10 75 data.frame list
11 75 data.frame list
12 75 data.frame list
21A 75 data.frame list
...
I now want to create a data frame for each MDC with the corresponding name, e.g. 'MDC1'.
How can I assign the MDC values to the list elements?
Thanks
It seems like this should work
MDC <- paste0("MDC", sort(unique(mydata$MDC)))
names(mylist) <- MDC
list2env(mylist, .GlobalEnv)
ls() # Checking environment
## [1] "MDC" "MDC21A" "MDC5" "MDC8" "mydata" "mylist"
Edit:
Per #flodel's comment- In case you want to make further operations on these data frames, you shouldn't copy them into the global environment. You should leave them in mylist and do all your operation on that list using functions such as lapply and rapply

Subtract column-specific value for a particular row from all values in data frame, in R

I have a data object signal in R with 40,000+ rows (named variables) of numeric values and 200+ columns (samples). For every row of each column, I want to subtract the value for the row named background for that column.
The code below can be used to create an example signal object in R. With the example, for column A, the background value of 4 is to be subtracted from the values of channelNo1 to 3. Similarly, for column B, the value of 6 is to be subtracted. And so on. What is the simplest way to achieve this in R?
text <- textConnection('
A B C
channelNo1 12 22 32
channelNo2 13 21 33
channelNo3 12 21 30
background 4 6 8
')
signal <- read.table(text, header = TRUE)
close(text)
typeof(signal)
# returns 'list'
class(signal)
# returns 'data.frame'
Elements in an R matrix are oriented by column (check out matrix(1:12, nrow=3) and signal - signal[4,] is not doing what you think -- check out column B, where the second and third values should be the same (and equal to 15). You could write
as.data.frame(Map("-", signal, as.vector(signal[4,])))
(I think this would be relatively efficient) but since the data really seem to be a matrix (i.e., a rectangle of homogeneous type) it makes a lot more sense to manipulate it as a matrix
m = as.matrix(signal)
sweep(m, 2, m[4,], "-")

how to turn values in dataframe into objects

For a function that I am writing, the output is a dataframe. But how do i assign the values that are in one of the columns of my dataframe to objects?
For example, if I have 2 vectors that I cbind into a dataframe
>numbers<-c(33, 44, 55, 66)
>names<-c("A", "B", "C", "D")
>MYdataframe<-data.frame(cbind(names, numbers))
I will get this:
>MYdataframe
names numbers
1 A 33
2 B 44
3 C 55
4 D 66
But how do I assign the numbers (e.g. 33) to objects (e.g. A)
It does not look like a very good idea: your function would be assigning variables in the global environment, or in its parent environment, instead of returning something. If you want to return several values, you can put them in a named list, e.g., list(A=3.14, B=2.71), or a vector if they all have the same type (they do, if you can put them in a data.frame).
In addition, in your example, cbind converts the numbers into factors: I am not sure this is intentional.
However, if you really insist, this can be done with assign.
library(plyr)
d_ply( MYdataframe, "names", function(u)
assign( as.character(u$names[1]), u$numbers, envir=.GlobalEnv)
)
If you really wanted to use the character values as names and the numeric values as "names' for a numeric vector then this would do it:
names(numbers) <- names
numbers
# A B C D
#33 44 55 66
numbers["A"]
# A
# 33
Maybe you should say what you really want, as well as choosing names for your objects that are not function names (names is a function) will help us keep things sorted out in our heads.

Resources