Skip to content

Instantly share code, notes, and snippets.

@timcdlucas
Created February 4, 2016 14:58
Show Gist options
  • Save timcdlucas/d1e0e8d4ced8d3946b2d to your computer and use it in GitHub Desktop.
Save timcdlucas/d1e0e8d4ced8d3946b2d to your computer and use it in GitHub Desktop.
Convert Mathematica array text to R array
#' Turn a string copied from Mathematica into an R array
#'
#'@param text Text representation of a mathematica array.
#'@param drop Logical. If TRUE, 1 and 2 dimensional arrays will be returned as vectors and matrices.
#' If FALSE, 1 and 2 dimensional arrays will be returned.
#'
#'@return An array
#'@export
#'@example
#'
#'a1 <- RMatr('{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}')
#'dim(a1)
#'a2 <- RMatr('{{2, 3}, {3, 4}, {4, 5}}')
#'dim(a2)
#'a3 <- RMatr('{{{22, 1111}, {3,3}}, {{3, 3}, {1, 4}}, {{0,4}, {9,5}}}')
#'dim(a3)
#'a4 <- RMatr('{{{{22, 1111}, {3,3}}, {{3, 3}, {1, 4}}, {{0,4}, {9,5}}}}')
#'dim(a4)
RMatr <- function(text, drop = TRUE){
# Calc number of dimensions
dim <- nchar(gsub('(^\\{*).*', '\\1', text))
# Remove whitespace then extra layer of brackets
text <- gsub(' ', '', text)
text <- gsub('^\\{|\\}$', '', text)
# Extract numbers
nums <- na.omit(as.numeric(strsplit(text, "[^[:digit:]]")[[1]]))
if(dim == 1) return(nums)
# Count number of elements at each dimension except last dimension
dimLengths <- rep(0, dim)
d <- 0
for(char in strsplit(text, '')[[1]]){
if(char == '{'){
d <- d + 1
} else if(char == '}'){
dimLengths[d] <- dimLengths[d] + 1
d <- d - 1
}
}
# Every element in 2nd dim is counted, but dim length is that divided by number of first dimensions.
if(dim > 2){
for(d in 2:(dim - 1)){
dimLengths[d] <- dimLengths[d] / prod(dimLengths[1:(d - 1)])
}
}
# Work out last dimension
dimLengths[length(dimLengths)] <- length(nums)/prod(dimLengths[1:(dim - 1)])
# Fill array. Have to fill in wrong order then permute dimensions.
arr <- array(nums, dim = rev(dimLengths))
arr <- aperm(arr, perm = dim:1)
if(dim == 2) arr <- as.matrix(arr)
if(dim == 1) arr <- as.vector(arr)
return(arr)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment