How to name the elements of an unnamed list - r

I have a list that look like this:
setlist2 <- list(wsb_b6, wsb_id8)
[[1]]
[1] "Gm10116" "Tpm3-rs7" "Wdfy1" "Rps3a2" "AK157302" "Gm6563"
"Gm9825" "Gm10259" "Gm6768"
[[2]]
[1] "Gm6401" "Ecel1" "Hpca" "Tmem176a" "Lepr"
"Baiap3" "Fam183b" "Vsx2" "Vtn"
I need it to look like this:
$wsb_b6
[1] "Gm10116" "Tpm3-rs7" "Wdfy1" "Rps3a2" "AK157302" "Gm6563"
"Gm9825" "Gm10259" "Gm6768"
$wsb_id8
[1] "Gm6401" "Ecel1" "Hpca" "Tmem176a" "Lepr"
"Baiap3" "Fam183b" "Vsx2" "Vtn"
I know that by doing it manually I can achieve it but it is more that 100 each, there's got to be a better way

#I found that I had to unlist my two previous lists
wsb_b6 <-wsb_b6[,1]
wsb_b6 <-unlist(wsb_b6)
wsb_id8 <-wsb_id8[,1]
wsb_id8 <- unlist(wsb_id8)
#And then list them again, but like this
setlist2 <-list(wsb_b6=wsb_b6, wsb_id8= wsb_id8)

Use dplyr::lst
setlist2 <- dplyr::lst(wsb_b6, wsb_id8)

It sounds like you want to create a named list. Specifically, you want to create a named list where the names are taken from the names of the variables in the environment.
This is similar to this question: Can lists be created that name themselves based on input object names?
I don't believe there is a simple function to do this in base R, but you can using the function llist from the package Hmisc:
library(Hmisc)
setlist2 <- llist(wsb_b6, wsb_id8)

Related

Use lists/dataframes as items in for-loops in R

I am quite sure this is basic stuff, but I just can't find the answer by googling. So my problem:
I want to use a for-loop on a list of lists or data frames. But when you use list[i], you get all the values in the data frame instead of the data frame it self. Can anyone point out to me how to code this properly?
Example of the code:
a<-data.frame(seq(1:3),seq(3:1))
b<-data.frame(seq(1:3),seq(3:1))
l<-c(a,b)
Then l[1] returns:
> l[1]
$seq.1.3..
[1] 1 2 3
And I want it to just return: a
You can use the list function:
a<-data.frame(1:3,1:3)
b<-data.frame(3:1,3:1)
l<-list(a,b)
And access it's value with double brackets [[:
l[[1]]
l[[2]]
Ps: seq(1:3) and seq(3:1) outputs the same value, so I used 1:3 and 3:1. :)

Looping/printing over a list in R

Let's suppose I have a simple list
v <- list(vec1=c(1,2,3), vec2=c(3,4,5, 6))
I would like to loop over this list and perform some function on its element, so that as an output I get both: name of that particular element and output of the function. For example:
for (i in v)
{print(sd(i))
}
In this case, the output is:
[1] 1
[1] 1.290994
But I would like to see something like this:
$vec1
[1] 1
$vec2
[1] 1.290994
So that I can easily spot to which element each output refers, if I have many elements within my list. I know it has sth with the function names() to do, but I can't make it work.
Using the function names() and outputting a list:
result<-list()
for (i in 1:length(v))
{result[[i]]=sd(v[[i]])
}
names(result)<-names(v)
The downside of this method is that it will assign the wrong names if the resulting list is smaller or greater than the original list (for example, if you add a next statement on the loop or otherwise skip an element).
If possible, a much easier solution is to follow d.b's comment.

R equivalent to the MATLAB structure?

Is there an R type equivalent to the Matlab structure type?
I have a few named vectors and I try to store them in a data frame. Ideally, I would simply access one element of an object and it would return the named vectors (like a structure in Matlab). I feel that using a data frame is not the right thing to do since it can store the values of the named vectors but not the names when they differ from one vector to the other.
More generally, is it possible to store a bunch of different objects in a single one in R?
Edit: As Joran said I think that list does the job.
l = list()
l$vec1 = namedVector1
l$vec2 = namedVector2
...
If I have a list of names
name1 = 'vec1'
name2 = 'vec2'
is there any way for the interpreter to understand that when I use a variable name like name1, I am not referring to the variable name but to its content? I have tried get(name1) but it does not work.
I could still be wrong about what you're trying to do, but I think this is the best you're going to get in terms of accessing each list element by name:
l <- list(a= 1:3,b = 1:10)
> ind <- "a"
> l[[ind]]
[1] 1 2 3
Namely, you're going to have to use [[ explicitly.

basic R question on manipulating dataframes

I have a data frame with several columns. rows have names.
I want to calculate some value for each row (col1/col2) and create a new data frame with the original row names. If I just do something like data$col1/data$col2 I get a vector with the results but lose the row names.
i know it's very basic but I'm quite new to R.
It would help to read ?"[.data.frame" to understand what's going on. Specifically:
Note that there is no ‘data.frame’
method for ‘$’, so ‘x$name’ uses the
default method which treats ‘x’ as a
list.
You will see that the object's names are lost if you convert a data.frame to a list (using Joris' example data):
> as.list(Data)
$col1
[1] -0.2179939 -2.6050843 1.6980104 -0.9712305 1.6953474 0.4422874
[7] -0.5012775 0.2073210 1.0453705 -0.2883248
$col2
[1] -1.3623349 0.4535634 0.3502413 -0.1521901 -0.1032828 -0.9296857
[7] 1.4608866 1.1377755 0.2424622 -0.7814709
My suggestion would be to avoid using $ if you want to keep row names. Use this instead:
> Data["col1"]/Data["col2"]
col1
a 0.1600149
b -5.7435947
c 4.8481157
d 6.3816918
e -16.4146120
f -0.4757387
g -0.3431324
h 0.1822161
i 4.3114785
j 0.3689514
use the function names() to add the names :
Data <- data.frame(col1=rnorm(10),col2=rnorm(10),row.names=letters[1:10])
x <- Data$col1/Data$col2
names(x) <- row.names(Data)
This solution gives a vector with the names. To get a data-frame (solution from Marek) :
NewFrame <- data.frame(x=Data$col1/Data$col2,row.names=row.names(Data))
A very simple and neat way is to use row.names(data frame) to store it as a column and further manipulate

how do I get the difference between two R named lists?

OK, I've got two named lists, one is "expected" and one is "observed". They may be complex in structure, with arbitrary data types. I want to get a new list containing just those elements of the observed list that are different from what's in the expected list. Here's an example:
Lexp <- list(a=1, b="two", c=list(3, "four"))
Lobs <- list(a=1, c=list(3, "four"), b="ni")
Lwant <- list(b="ni")
Lwant is what I want the result to be. I tried this:
> setdiff(Lobs, Lexp)
[[1]]
[1] "ni"
Nope, that loses the name, and I don't think setdiff pays attention to the names. Order clearly doesn't matter here, and I don't want a=1 to match with b=1.
Not sure what a good approach is... Something that loops over a list of names(Lobs)? Sounds clumsy and non-R-like, although workable... Got any elegant ideas?
At least in this case
Lobs[!(Lobs %in% Lexp)]
gives you what you want.
OK, I found one slightly obtuse answer, using the plyr package:
> Lobs[laply(names(Lobs), function(x) !identical(Lobs[[x]], Lexp[[x]]))]
$b
[1] "ni"
So, it takes the names of the array from the observed function, uses double-bracket indexing and the identical() function to compare the sub-lists, then uses the binary array that results from laply() to index into the original observed function.
Anyone got a better/cleaner/sexier/faster way?

Resources