Matlab Cell Array Import via R fails - r

I am facing the following problem. I try to import a cell of strings with the readMat function in R.
Matlab Code:
Names = {'A', 'B', 'C', 'D'};
save('RDataIn.mat', 'Names');
Now i want to use the set of strings in R. I run to following R script
R Code:
library('R.matlab')
Names <- readMat("RDataIn.mat")
readMat can for apparently not handle cell type .mat data, it creates some strange list. Anyone a solution to this problem? Thanks.

Yeah.... it's pretty weird like that. I wouldn't say it "fails", but it's in a format that requires some work. This is what I get when I save the above cell array and load it into R:
> library("R.matlab")
> Names <- readMat("RDataIn.mat")
> Names
$Names
$Names[[1]]
$Names[[1]][[1]]
[,1]
[1,] "A"
$Names[[2]]
$Names[[2]][[1]]
[,1]
[1,] "B"
$Names[[3]]
$Names[[3]][[1]]
[,1]
[1,] "C"
$Names[[4]]
$Names[[4]][[1]]
[,1]
[1,] "D"
attr(,"header")
attr(,"header")$description
[1] "MATLAB 5.0 MAT-file, Platform: MACI64, Created on: Sat Mar 28 13:12:31 2015 "
attr(,"header")$version
[1] "5"
attr(,"header")$endian
[1] "little"
As you can see, Names contains a nested list where each string is stored in a 1 x 1 matrix. What you can do is access the only element of this list, then within this list, go through all of the elements and extract out the first element of each nested element. This contains each "name" or string you're looking for. You can use a standard sapply call for that and for each element in the list, apply a custom function that would extract out the first element of each nested element for you.
x <- sapply(Names[[1]], function(n) n[[1]])
x would be a vector of names, and I get:
> x
[1] "A" "B" "C" "D"
You can access each "name" by standard vector indexing:
> x[1]
[1] "A"
> x[2]
[1] "B"
> x[3]
[1] "C"
> x[4]
[1] "D"

Related

Working with names and values of objects in a list in R using loops

how do you retrieve the names of the objects of a list in a loop. I want to do something like this:
lst = list(a = c(1,2), b = 1)
for(x in lst){
#print the name of the object x in the list
# print the multiplication of the values
}
Desired results:
"a"
2 4
"b"
2
In Python one can use dictionary and with the below code get the desired results:
lst = {"a":[1,2,3], "b":1}
for key , value in lst.items():
print(key)
print(value * 2)
but since in R we have no dictionary data structure, I am trying to achieve this using lists but I don't know how to return the objects names. Any help would be appreciated.
We can get the names directly
names(lst)
[1] "a" "b"
Or if we want to print in a loop, loop over the sequence or names of the list, print the name, as well as the value got by extracting the list element based on the name multiplied
for(nm in names(lst)) {
print(nm)
print(lst[[nm]] * 2)
}
[1] "a"
[1] 2 4
[1] "b"
[1] 2
Or another option is iwalk
library(purrr)
iwalk(lst, ~ {print(.y); print(.x * 2)})
[1] "a"
[1] 2 4
[1] "b"
[1] 2

Access second to last element of vectors nested in list in R

*Similar questions exist, but don't respond my specific question.
In a nested list, what's an elegant way of accessing the second to last element of each vector. Take the following list:
l <- list(c("a","b","c"),c("c","d","e","f"))
How do I produce a new list (or vector) which contains the second to last element of each vector in list l? The output should look like this:
[[1]]
[1] "b"
[[2]]
[1] "e"
I access the last element of each vector via lapply(l,dplyr::last), but not sure how to select the second to last elements. Much appreciated.
Try this:
l <- list(c("a","b","c"),c("c","d","e","f"))
lapply(l, function(x) x[length(x) -1])
#> [[1]]
#> [1] "b"
#>
#> [[2]]
#> [1] "e"

How To Add Characters Around Elements

I am using R and want to covert following:
"A,B"
to
"A","B" OR 'A','B'
I tried str_replace(), but that's not working out.
Please suggest, thanks.
Update
I tried the suggested answer by d.b. Though it works, but I didn't realize that I should have shared that, I am going to use above solution for vector. I need the values in data with "A,B" to split in order to use it as a vector.
Using strsplit
> data
[1] "A,B"
> test <- strsplit(x = data, split = ",")
> test
[[1]]
[1] "A" "B"
above test won't be useful because I can't use it for following:
> output_1 <- c(test)
> outputFinalData <- outputFinal[outputFinal$Column %in% output_1,]
outputFinalData is empty with above process. But is not empty when I do:
> output_2 <- c("A", "B")
> outputFinalData <- outputFinal[outputFinal$Column %in% output_2,]
Also, output_1 and output_2 are not same:
> output_1
[[1]]
[1] "Bin_14" "Bin_15"
> output_2
[1] "Bin_14" "Bin_15"
> output_1 == output_2
[1] FALSE FALSE
Use strsplit:
> data = "A,B"
> strsplit(x=data,split=",")
[[1]]
[1] "A" "B"
Note that it returns a list with a vector. The list is length one because you asked it to split one string. If you ask it to split two strings you get a list of length 2:
> data = c("A,B","Foo,bar")
> strsplit(x=data,split=",")
[[1]]
[1] "A" "B"
[[2]]
[1] "Foo" "bar"
So if you know you are only going to have one thing to split you can get a vector of the parts by taking the first element:
> data = "A,B"
> strsplit(x=data,split=",")[[1]]
[1] "A" "B"
However it might be more efficient to do a load of splits in one go and put the bits in a matrix. As long as you can be sure everything splits into the same number of parts, then something like:
> data = c("A,B","Foo,bar","p1,p2")
> do.call(rbind,(strsplit(x=data,split=",")))
[,1] [,2]
[1,] "A" "B"
[2,] "Foo" "bar"
[3,] "p1" "p2"
>
Gets you the two parts in columns of a matrix that you can then add to a data frame if that's what you need.

extracting element of a vector based on index given in a list in R

I am looking to extract elements of a character vector based of the index in a list. For eg: I have a vector CV and index that I will like to extract are in a list AL. I can extract them individually (through a loop) but I was wondering if there's a way that I can do it without having to use the loop (perhaps using apply function). I tried using sapply unsuccessfully.
CV = c("a","b","c","d")
AL = list(c(1,2),c(2,3,4),c(2))
CV[AL[[1]]]
[1] "a" "b"
sapply(CC,'[',AL)
Your problem is that
sapply(CV,'[',AL)
will (attempt to) iterate over each element of CV, but you want to iterate over each element of AL:
sapply(AL, function(z) CV[z])
# [[1]]
# [1] "a" "b"
#
# [[2]]
# [1] "b" "c" "d"
#
# [[3]]
# [1] "b"

R How do I create a dataframe containing a column of lists?

This is my current work around:
> df=data.frame(a=1)
> df$b = list(list(2,'a'))
> df
a b
1 1 2, a
It works, and I don't really mind that df=data.frame(a=1,b=list(list(1,'a'))) doesn't work .
But referencing b requires [[]] notation, like this: df$b[[1]].
I'm looking for a solution that would allow simply df$b.
What you're looking for is not possible. If you use lists, you will need to use the [[]] notation. Otherwise, you can transform the elements of df$b using the command unlist().
> df$b
[[1]]
[[1]][[1]]
[1] 2
[[1]][[2]]
[1] "a"
> unlist(df$b)
[1] "2" "a"
> unlist(df$b)[1]
[1] "2"
> unlist(df$b)[2]
[1] "a"

Resources