R: Assign value to a character row from dataframe

Viewed 196

Hi how can I assign value to the 1st column characters that is based on the 2nd column. See my sample dataframe below.

> Code <- c('A','B','C','D','E')
> Value <- c(1.23,1.4,1.55,1.67,1.3)
> ds <- data.frame(Code, Value)
> ds
  Code Value
1    A  1.23
2    B  1.40
3    C  1.55
4    D  1.67
5    E  1.30

Now for example when I type "A" in the R console it should have a value of 1.23. Not error as shown below.

> A
Error: object 'A' not found

Desired output is.

> A
[1] 1.23

It should also work in Codes B to E.

5 Answers

Having many global variables is not recommended, however, here is a way :

list2env(split(ds$Value, ds$Code), .GlobalEnv)

A
#[1] 1.23
B
#[1] 1.4

And yet another way, here using assign() and a for loop:

for(i in seq_len(nrow(ds))) {
  assign(ds$Code[i], ds$Value[i])
}

Another base R option using setNames + list2env

list2env(with(ds, setNames(as.list(Value), Code)), .GlobalEnv)

or eval + str2expression (this option is NOT recommended)

eval(str2expression(do.call(paste, c(ds, sep = "<-", collapse = ";"))))

Not exactly what you are asking for (I wouldn't add all the rows as global variables). Instead this solutions keeps your data.frame as a data.table with a key which allows you to retrieve the relevant row in a concise way:

library(data.table)
setDT(ds)
setkey(ds, Code)

ds["B", Value]
# [1] 1.4

You could also use a named list:

x <- setNames(as.list(ds$Value), ds$Code)
x$B
# [1] 1.4

You can use attach to access values of a named list.

attach(setNames(as.list(ds$Value), ds$Code))
A
#[1] 1.23
D
#[1] 1.67

#And remove it again with
detach()

Or you can use assign in mapply

mapply(assign, ds$Code, ds$Value, MoreArgs = list(envir = .GlobalEnv))

or with Vectorize

Vectorize(assign, c("x", "value"))(ds$Code, ds$Value, envir = .GlobalEnv)
Related