1

I'm trying to make objects directly from information listed in a tibble that can be called on by later functions/tibbles in my environment. I can make the objects manually but I'm working to do this iteratively.

library(tidyverse)    
##determine mean from 2x OD Negatives in experimental plates, then save summary for use in appending table

ELISA_negatives = "my_file.csv"  
neg_tibble <- as_tibble(read_csv(ELISA_negatives, col_names = TRUE))  %>%
  group_by(Species_ab, Antibody, Protein) %>% 
  filter(str_detect(Animal_ID, "2x.*")) %>%
  summarize(ave_neg_U_mL = mean(U_mL, na.rm = TRUE), n=sum(!is.na(U_mL))) 

neg_tibble
# A tibble: 4 x 5
# Groups:   Species_ab, Antibody [2]
  Species_ab Antibody Protein ave_neg_U_mL     n
  <chr>      <chr>    <chr>          <dbl> <int>
1 Mouse      IgG      GP             28.2      6
2 Mouse      IgG      NP             45.9      6
3 Rat        IgG      GP              5.24     4
4 Rat        IgG      NP              1.41     1

I can write the object manually based off the above tibble:

Mouse_IgG_GP_cutoff <- as.numeric(neg_tibble[1,4])
Mouse_IgG_GP_cutoff
[1] 28.20336

In my attempt to do this iteratively, I can make a new tibble neg_tibble_string with the information I need. All I would need to do now is make a global object from the Name in the first column Test_Name, and assign it to the numeric value in the second column ave_neg_U_mL (which is where I'm getting stuck).

 neg_tibble_string <- neg_tibble %>%
      select(Species_ab:Protein) %>%
      unite(col='Test_Name', c('Species_ab', 'Antibody', 'Protein'), sep = "_") %>%
      mutate(Test_Name = str_c(Test_Name, "_cutoff")) %>%
      bind_cols(neg_tibble[4])
    
    neg_tibble_string
        # A tibble: 4 x 2
      Test_Name           ave_neg_U_mL
      <chr>                      <dbl>
    1 Mouse_IgG_GP_cutoff        28.2 
    2 Mouse_IgG_NP_cutoff        45.9 
    3 Rat_IgG_GP_cutoff           5.24
    4 Rat_IgG_NP_cutoff           1.41

I feel like there has to be a way to do this to get this from the above tibble neg_tibble_string, and make this for all four of the rows. I've tried a variant of this and this, but can't get anywhere.

> list_df <- mget(ls(pattern = "neg_tibble_string"))
> list_output <- map(list_df, ~neg_tibble_string$ave_neg_U_mL)
Warning message:
Unknown or uninitialised column: `ave_neg_U_mL`. 
> list_output
$neg_tibble_string
NULL

As always, any insight is appreciated! I'm making progress on my R journey but I know I am missing large gaps in knowledge.

allisonrs
  • 102
  • 8
  • You can create separate objects, but is there a reason you don't want to keep the data frame and pull specific values as needed? – eipi10 Oct 06 '21 at 17:49
  • I would be using the created object the filter rows, based off groupings in other dataframes. For example, keep only rows when the value is greater than a certain number (the number in this data frame) for a particular grouping of data (the Test_Name in this dataframe). – allisonrs Oct 06 '21 at 17:54

1 Answers1

2

As we already returned the object value in a list, we need only to specify the lambda function i.e. .x returns the value of the list element which is a tibble and extract the column

library(purrr)
list_output <- map(list_df,  ~.x$ave_neg_U_ml)

If the intention is to create global objects, deframe, convert to a list and then use list2env

library(tibble)
list2env(as.list(deframe(neg_tibble_string)), .GlobalEnv)
akrun
  • 874,273
  • 37
  • 540
  • 662
  • I can get `list_output` now. `$neg_tibble_string` `[1] 28.203360 45.894141 5.237439 1.411760` > list2env(as.list(deframe(neg_tibble_string)), .GlobalEnv) ` – allisonrs Oct 06 '21 at 17:55
  • @allisonrs the second case is creating global objects with names from `Test_Name` column. So if you check `Mouse_IgG_GP_cutoff` value will be 28.2 – akrun Oct 06 '21 at 17:59
  • Oh wow, that was quick and easy. Thanks! Would you mind explaining how exactly the deframe and as.list work together? Deframe takes the two column tibble and makes two lists, then as.list puts them back together row-wise? – allisonrs Oct 06 '21 at 18:02
  • 1
    @allisonrs it is similar to creating a named vector (`deframe`) and then convert to list with `as.list` i.e. `with(neg_tibble_string, as.list(setNames(ave_neg_U_mL, Test_Name)))` – akrun Oct 06 '21 at 18:03
  • RE first comment -- I initially couldn't find where they were because when I printed the list2env again, all I got for output was ``, I was looking to see them actually printed. I found them and they call as expected. Thank you again! – allisonrs Oct 06 '21 at 18:03
  • @allisonrs you can check the `ls()` to see the new object names – akrun Oct 06 '21 at 18:04