Created
February 4, 2016 14:58
-
-
Save timcdlucas/d1e0e8d4ced8d3946b2d to your computer and use it in GitHub Desktop.
Convert Mathematica array text to R array
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#' 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