How to add variable key/value pair to list object? - list

I have two variables, key and value, and I want to add them as a key/value pair to a list:
key = "width"
value = 32
mylist = list()
mylist$key = value
The result is this:
mylist
# $key
# [1] 32
But I would like this instead:
mylist
# $width
# [1] 32
How can I do this?

R lists can be thought of as hashes- vectors of objects that can be accessed by name. Using this approach you can add a new entry to the list like so:
key <- "width"
value <- 32
mylist <- list()
mylist[[ key ]] <- value
Here we use the string stored in the variable key to access a position in the list much like using the value stored in a loop variable i to access a vector through:
vector[ i ]
The result is:
myList
$width
[1] 32

The setNames() built-in function makes it easy to create a hash from given key and value lists. (Thanks to Nick K for the better suggestion.)
Usage: hh <- setNames(as.list(values), keys)
Example:
players <- c("bob", "tom", "tim", "tony", "tiny", "hubert", "herbert")
rankings <- c(0.2027, 0.2187, 0.0378, 0.3334, 0.0161, 0.0555, 0.1357)
league <- setNames(as.list(rankings), players)
Then accessing the values through the keys is easy:
league$bob
[1] 0.2027
league$hubert
[1] 0.0555

List elements in R can be named. So in your case just do
> mylist = list()
> mylist$width = value
When R encounters this code
> l$somename=something
where l is a list. It appends to a list an element something, and names it with name somename. It is then can be accessed by using
> l[["somename"]]
or
> l$somename
The name can be changed with command names:
> names(l)[names(l)=="somename"] <- "othername"
Or if you now the position of the element in the list by:
> names(l)[1] <- "someothername"

We can use R's list data structure to store data in the form of key-value pair.
Syntax:
ObjectName<-list("key"= value)
Example:
mylist<-list("width"=32)
also, refer example: "https://github.com/WinVector/zmPDSwR/blob/master/Statlog/GCDSteps.R"

Related

How to generate the random values of map from a given set of values and then store the key and values into separate variables in scala

I am trying to generate the 1000 random key-val map pairs from the given(statically defined) 2 map key-val pairs in scala and also later i would want to break the key and value pairs and store them into separate variables
Whatever i have tried:
object methodTest extends App{
val testMap = Map("3875835"->"ABCDE","316067107"->"EFGHI")
def getRandomElement(seq: Map[String,String]): Map[String,String] = {
seq(Random.nextInt(seq.length))
}
var outList = List.empty[Map[String,String]]
for(i<-0 to 1000){
outList+=getRandomElement(testMap)
}
print(outList)
}
The Output should generate 1000 Key-val pairs of map like i am showing below
[3875835,ABCDE]
[316067107,EFGHI]
[3875835,ABCDE]
[316067107,EFGHI]
[316067107,EFGHI]
............
............
............. upto 1000 random key-val pairs
Please help me figure out where i am going wrong and let me know How to resolve it, if any issue regarding the requirement, please feel free to comment for it
You can transform your seed map testMap into sequence of key/value tuples using .toSeq and then generate key/value pairs by iterating over the list of numbers from 0 until 1000, associating each number to a random choice between first or second element of the seed:
import scala.util.Random
val testMap = Map("3875835" -> "ABCDE", "316067107" -> "EFGHI")
val seed = testMap.toSeq
val keyValuesList = (0 until 1000).map(index => seed(Random.nextInt(seed.size)))
Note: 0 until 1000 will return all the numbers from 0 to 1000 excluded, so 1000 numbers. If you use 0 to 1000 you will get all the numbers from 0 to 1000 included, so 1001 numbers.
If you want to print the resulting list, you can use .foreach method with println function as argument:
keyValuesList.foreach(println)
And you will get:
(3875835,ABCDE)
(316067107,EFGHI)
(3875835,ABCDE)
(3875835,ABCDE)
(316067107,EFGHI)
(3875835,ABCDE)
...
if you want to keep only the keys, you can iterate on the list using .map method, taking only the first element of the tuple by using ._1 method, that retrieve the first element of a tuple:
val keys = keyValuesList.map(keyValuePair => keyValuePair._1)
And if you want only a list containing all second elements of each pair:
val values = keyValuesList.map(keyValuePair => keyValuePair._2)

Function to subset dataframe using pattern list argument

I have a pattern list
patternlist <- list('one' = paste(c('a','b','c'),collapse="|"), 'two' = paste(1:5,collapse="|"), 'three' = paste(c('k','l','m'),collapse="|"))
that I want to select from to extract rows from a data frame
dataframez <- data.frame('letters' = c('a','b','c'), 'numbers' = 1:3, 'otherletters' = c('k','l','m'))
with this function
pattern.record <- function(x, column="letters", value="one")
{
if (column %in% names(x))
{
result <- x[grep(patternlist$value, x$column, ignore.case=T),]
}
else
{
result <- NA
}
return(result)
}
oddly enough, I get an error when I run it:
> pattern.record(dataframez)
Error in grep(patternlist$value, x$column, ignore.case = T) :
invalid 'pattern' argument
The problem is your use of the `$` operator.
In your function, it is looking a column \ named element called column
It is far simpler here to use `[[`
Then x[[column]] uses what column is defined as, not column as a name.
The relevant lines in ?`$` are
Both [[ and $ select a single element of the list. The main difference is that $ does not allow computed indices, whereas [[ does. x$name is equivalent to x[["name", exact = FALSE]]. Also, the partial matching behavior of [[ can be controlled using the exact argument.
You are trying to use value and column as computed indices (i.e. computing what value and column are defined as), thus you need `[[`.
The function becomes
pattern.record <- function(x, column="letters", value="one", pattern_list)
{
if (column %in% names(x))
{
result <- x[grep(pattern_list[[value]], x[[column]], ignore.case=T),]
}
else
{
result <- NA
}
return(result)
}
pattern.record(dataframez, patternlist = pattern_list)
## letters numbers otherletters
## 1 a 1 k
## 2 b 2 l
## 3 c 3 m
note that I've also added an argumentpattern_list so it does not depend on an object named patternlist existing somewhere in the parent environments (in your case the global environment.

Inserting elements in an R list

I want to store a few entries in a "dictionary" so that I can retreive them by name. I can form something like that indirectly like this:
> a = list(c(1,2),c(9,9,0,0))
> names(a) = c("first","second")
> a
$first
[1] 1 2
$second
[1] 9 9 0 0
However, I can't do the same thing by simply inserting them by name like this:
> a=list()
> a["first"] = c(1,2)
Warning message:
In a["first"] = c(1, 2) :
number of items to replace is not a multiple of replacement length
> a
$first
[1] 1
Why is this so, and what syntax should I use to insert objects like vectors or matrices by name into a list?
Your problem is that you are using [ rather than [[. This should work:
a[['first']] <- c(1,2)
as should this:
a$first <- c(1,2)
Remember, [ gives you a sublist, while [[ accesses specific elements.
You got one good answer. Here's an equivalent answer:
a=list()
a["first"] = list(c(1,2))
a
# $first
# [1] 1 2
So to expand on joran's perfectly fine answer, you are really using [<- as a function, and it both gives (via [) and receives (via[<-) lists.
Just because a function returns something is not a promise that it will set something.

R: combine lists of interest

I have a list like df_all (see below).
A = matrix( ceiling(10*runif(8)), nrow=4)
colnames(A) = c("country", "year_var")
dfa = data.frame(A)
df1 = dfa[1,]
df2 = dfa[2,]
df3 = dfa[3,]
df4 = dfa[4,]
df_all = list(df1, df2, df3, df4)
df_all
Now I want to combine the list of interest by using variable a.
a <- "2,3,4"
b <- strsplit(a, ",")[[1]]
To combine this lists, I use the folling loop:
for (i in 1:length(b)){
c<-b[i]
aa <- df_all[c:c]
print(aa)
}
Now my question is, How can I combine this result and save this as as variable?
Thanks!
Would this work for you:
basnum<-as.integer(b)
do.call(rbind, df_all[basnum])
Through df_all[basnum], a list with only the relevant data.frames is created.
do.call takes a function and a list as parameters (and some more but not relevant right now). The items of the list are then passed on as parameters to the function.
So in this case, the above is the equivalent to calling:
rbind(df_all[[2]], df_all[[3]], df_all[[4]])
And this produces one data.frame holding all the rows of interest.

How to transform a matrix with 2 columns into a multimap like structure?

I am wondering if there is a way to transform a matrix of 2 columns into a multimap or list of list.
The first column of the matrix is an id (with possibly duplicated entries) and the 2nd column is some value.
For example,
if I have to following matrix
m <- matrix(c(1,2,1,3,2,4), c(3,2))
I would like to transform it into the following list
[[1]]
3,4
[[2]]
2
With base functions, you can do something like this:
tapply(m[,2], m[,1], `[`) # outputs an array
by(m, m[,1], function(m) m[,2]) # outputs a by object, which is a list
You could use plyr:
dlply(m, 1, function(m) m[,2]) # outputs a list
dlply(m, 1, `[`, 2) # another way to do it...