Looking for the smartest and shortest way to bind the following two arrays in R. Excepted output is also given...
#Creating two arrays
(a <- array(c(1:9,19:27), dim = c(3,3,2)))
(b <- array(c(10:18,28:36), dim = c(3,3,2)))
#Wanted array by binding a and b
(wanted <- array(1:36, dim = c(3,6,2)))
Thanks a lot...
We can use abind
library(abind)
res <- abind(a, b, along = 2)
attr(res, "dimnames") <- NULL
identical(res, wanted)
#[1] TRUE
Related
This question already has an answer here:
Select multiple elements from a list
(1 answer)
Closed 4 years ago.
I need help with extracting array from list.
array1 <- array(c(1,2,3), dim = c(3,3,3))
array2 <- array(c(10,20,30), dim = c(3,3,3))
A <- list(array1,array2)
B <- A[1]
"A" is list of two arrays. When I want to extract for example first array and assign it to "B", B isn't array, but it is also list. How can I access data stored in B? B[1,1,1] doesn't work.
Use [[ to extract element in a list. If you use [, the output would still be a list.
array1 <- array(c(1,2,3), dim = c(3,3,3))
array2 <- array(c(10,20,30), dim = c(3,3,3))
A <- list(array1,array2)
B <- A[[1]]
If we are using magrittr, then extract2 can be used for the same purpose
library(magrittr)
B <- A %>%
extract2(1)
Looking for the smartest and shortest code to solve the following issue in R. Two non-proper solutions are provided...
#Generating a multi-layered list
m <- matrix(1:50, ncol = 5, byrow = TRUE)
mList <- list(m[1:5,], m[6:10,])
mList
#Transforming list to array: Option one
mArrayOne <- array(c(mList[[1]], mList[[2]]), dim = c(5,5,2))
mArrayOne
#Transforming list to array: Option two
mArrayTwo <- array(numeric(), dim = c(dim(mList[[1]]), length(mList)))
for(i in 1:length(mList)){mArrayTwo[,,i] <- mList[[i]]}
mArrayTwo
Any hint is welcome - thanks...
We can just unlist the list and create the array
array(unlist(mList), dim = c(5,5,2))
When trying to multiply the first dimension of an array by each index of a vector by the second dimension, my array is converted to a matrix and things get squirrelly. I can only do the proper multiplication long-hand.
What a mouth full...
It's easier to explain with code...
Arr <- array(runif(10*5*3), dim = c(10,5,3))
dim(Arr)
Vect <- c(1:5)
Arr[,1,1] <- Arr[,1,1]*Vect[1]
Arr[,1,2] <- Arr[,1,2]*Vect[1]
Arr[,1,3] <- Arr[,1,3]*Vect[1]
Arr[,2,1] <- Arr[,2,1]*Vect[2]
Arr[,2,2] <- Arr[,2,2]*Vect[2]
Arr[,2,3] <- Arr[,2,3]*Vect[2]
Arr[,3,1] <- Arr[,3,1]*Vect[3]
Arr[,3,2] <- Arr[,3,2]*Vect[3]
Arr[,3,3] <- Arr[,3,3]*Vect[3]
Arr[,4,1] <- Arr[,4,1]*Vect[4]
Arr[,4,2] <- Arr[,4,2]*Vect[4]
Arr[,4,3] <- Arr[,4,3]*Vect[4]
Arr[,5,1] <- Arr[,5,1]*Vect[5]
Arr[,5,2] <- Arr[,5,2]*Vect[5]
Arr[,5,3] <- Arr[,5,3]*Vect[5]
How do I clean this up to be one command?
Try:
sweep(Arr,2,Vect,FUN="*")
Cast Vect into an array first, then element multiply:
varr <- aperm(array(Vect, dim = c(5L, 10L, 3L)), perm = c(2L, 1L, 3L))
Arr <- varr * Arr
(of course we don't need to store varr if you want this in one command)
(also, turns out this is basically what sweep does under the hood...)
The aaply() function from the plyr package does exactly what you're looking for. It can operate on arrays of any dimension and split them however you like. In this case you're splitting by rows so:
library(plyr)
Arr2 <- aaply(Arr, 1, function(x,y){x*y}, Vect)
We can also replicate the 'Vect' and multiply with 'Arr'. The col is a convenient function that gives the numeric index of columns.
res1 <- Arr * Vect[col(Arr[,,1])]
Or we explicitly do the rep
res2 <- Arr* rep(Vect, each=dim(Arr)[1])
identical(res1, res2)
#[1] TRUE
I have two arrays coming from a postgreSQL database as following.
iarray
{9.467182035,9.252423958,9.179368178,9.142931845,9.118895803,9.098669713,9.093398102,9.092035392,9.091328028,9.090594437,9.090000456,9.089253543......keeps going on}
varray
{-1.025945126,-0.791203874,-0.506481774,-0.255416444,-0.028424464,0.188855034,0.390787963,0.579327969,0.761521769 ...keeps going on}
Both arrays have equal number of entries. I want to convert these to a data frame hence I can draw a graph of i over v.
How should I proceed?
I tried n<-gsub("^\\{+(.+)\\}+$", '\\1', iarray) to remove the {} and
n2 <- strsplit(n, ",") to remove the commas.
Assuming you are getting iarray & varray as strings :
iarray = "{9.467182035,9.252423958,9.179368178,9.142931845}"
varray = "{-1.025945126,-0.791203874,-0.506481774,-0.255416444}"
n<-gsub("^\\{+(.+)\\}+$", '\\1', iarray)
n1 <- strsplit(n,",")
n1 <- unlist(n1)
df <- as.data.frame(n1)
n<-gsub("^\\{+(.+)\\}+$", '\\1', varray)
n2 <- strsplit(n,",")
n2 <- unlist(n2)
df <- cbind(df,n2)
This seems one of the few occasions to correctly use eval(parse()):
df<-list(iarray,varray)
df<-data.frame(lapply(df,
function(x) eval(parse(text=sub("\\}$",")",sub("^\\{","c(",x))))
))
names(df)<-c("iarray","varray")
We just replace the { with (, add a c at the beginning and iarray and varray become command lines to create vectors which we parse and eval.
I want to make array in 3 dimension.
Here is what I tried:
z<-c(160,720,420)
first_data_set <-array(dim = length(file_1), dimnames = z)
Data that I am reading is in one level. (only x and y)
There are other data in the same format, and I need to put them in the same array with the first data. So once I finish reading all data, all of them are in the same array but there is no overwriting.
So I think array has to be 3 dimensions; otherwise I cannot keep all data that I read in loop.
Say that you have two matrices of size 3x4:
m1 <- matrix(rnorm(12), nrow = 3, ncol = 4)
m2 <- matrix(rnorm(12), nrow = 3, ncol = 4)
If you want to place them in an array, first make an array of NA's:
A <- array(as.numeric(NA), dim = c(3,4,2))
Then populate the layers with data:
A[,,1] <- m1
A[,,2] <- m2
As suggested by #Justin, you could also just put the matrices together in a list:
A2 <- list()
A2[['m1']] <- m1
A2[['m2']] <- m2
To read matrices from files: using a list makes it easier to get these matrices from files in a directory, without having to specify the dimensions in advance. Assume you want all files with extension csv:
myfiles <- dir(pattern = ".csv")
for (i in 1:length(myfiles)){
A2[[myfiles[i]]] <- read.table(myfiles[i], sep = ',')
}