Question

I need to convert a multi-row two-column data.frame to a named character vector. My data.frame would be something like:

dd = data.frame(crit = c("a","b","c","d"), 
                name = c("Alpha", "Beta", "Caesar", "Doris")
                )

and what I actually need would be:

whatiwant = c("a" = "Alpha",
              "b" = "Beta",
              "c" = "Caesar",
              "d" = "Doris")
Was it helpful?

Solution

Use the names function:

whatyouwant <- as.character(dd$name)
names(whatyouwant) <- dd$crit

as.character is necessary, because data.frame and read.table turn characters into factors with default settings.

If you want a one-liner:

whatyouwant <- setNames(as.character(dd$name), dd$crit)

OTHER TIPS

You can also use deframe(x) from the tibble package for this.

tibble::deframe()

It converts the first column to names and second column to values.

You can make a vector from dd$name, and add names using names(), but you can do it all in one step with structure():

whatiwant <- structure(as.character(dd$name), names = as.character(dd$crit))

Here is a very general, easy, tidy way:

library(dplyr)

iris %>%
  pull(Sepal.Length, Species)

The first argument is the values, the second argument is the names.

For variety, try split and unlist:

unlist(split(as.character(dd$name), dd$crit))
#        a        b        c        d 
#  "Alpha"   "Beta" "Caesar"  "Doris" 

There's also a magrittr solution to this via the exposition pipe (%$%):

library(magrittr)

dd %$% set_names(as.character(name), crit)

Minor advantage over tibble::deframe is that one doesn't have to have exactly a two-column frame/tibble as argument (i.e., avoid a select(value_col, name_col) %>%).

Note that the magrittr::set_names versus base::setNames is exchangeable. I simply prefer the former since it matches "set_(col|row)?names".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top