Make a list with every entry from a data-frame in rstudio

Viewed 62

I have a data-frame in rstudio as such:

Animal Color Weight
Deer Brown Less than 3
Pig Green More than 3

I want a list as such:

  • Deer-Color: Brown
  • Deer-Weight: Less than 3
  • Pig-Color: Green
  • Pig-Weight: Less than 3

How can I make that happen? There's way more entries and also more characteristics in the real-life application, and thus I would love an automated way.

Thank you!

5 Answers

If we have more columns, then an option is to use across to loop over the columns of interest, then with glue interpolate the column 'Animal' with the values of the current column along with column name of that column (cur_column())

library(dplyr)
df %>% 
  mutate(across(-Animal, ~ glue::glue("{Animal}-{cur_column()}: {.}"),
        .names = "{.col}_attributes"))
#  Animal Color      Weight  Color_attributes        Weight_attributes
#1   Deer Brown Less than 3 Deer-Color: Brown Deer-Weight: Less than 3
#2    Pig Green More than 3  Pig-Color: Green  Pig-Weight: More than 3

data

df <- structure(list(Animal = c("Deer", "Pig"), Color = c("Brown", 
"Green"), Weight = c("Less than 3", "More than 3")),
class = "data.frame", row.names = c(NA, 
-2L))

In base R using apply :

cols <- names(df)[-1]
apply(df, 1, function(x) sprintf('%s-%s', x[1], paste(cols, x[-1], sep = ':')))

#     [,1]                      [,2]                    
#[1,] "Deer-Color:Brown"        "Pig-Color:Green"       
#[2,] "Deer-Weight:Less than 3" "Pig-Weight:More than 3"

Do you want a list like below?

> Map(as.list,split(df[-1],df[1]))
$Deer
$Deer$Color
[1] "Brown"

$Deer$Weight
[1] "Less than 3"


$Pig
$Pig$Color
[1] "Green"

$Pig$Weight
[1] "More than 3"

If I understand correctly, the OP expects the output to be reshaped in long format (call it "list" or "vector").

Here is one possible approach which uses melt() and glue_data(). It will work with an arbitrary number of attribute columns.

glue::glue_data(
  data.table::melt(ds, id.var = "Animal"),
  "{Animal}-{variable}: {value}")
Deer-Color: Brown
Pig-Color: Green
Deer-Weight: Less than 3
Pig-Weight: More than 3

Alternatively, you may use tidyr::pivot_longer() for reshaping.

Data

ds <- data.table::fread(
"Animal,Color,   Weight
Deer,    Brown,   Less than 3
Pig, Green,   More than 3")

I'd break this down into smaller problems.

  1. Create the Animal-attribute pairs
  2. Create the "list". I'm assuming you mean vector.
Animal <- c("Deer", "Pig")
Color <- c("Brown", "Green")
Weight<-c("Less than 3","More than 3")

df <- data.frame(Animal, Color, Weight)

df_new<-df %>%
  mutate(Animal_attribute1=paste0(Animal,"-Color: ",Color)) %>%
  mutate(Animal_attribute2=paste0(Animal,"-Weight: ",Weight))

my_list<-c(df_new$Animal_attribute1,df_new$Animal_attribute2)
Related