d-math
d-math

Reputation: 61

Indexing problem while adding values defined by multiple other columns of tibbles within a list

I have a named list containing 4 tibbles:

list_all <- list("iris_a" = iris,
                 "iris_b" = iris,
                 "iris_c" = iris,
                 "iris_d" = iris)

Now I'd like to add for example the Petal.Length of the flower that has a Sepal.Length of 6.8 and Species == versicolor to the Petal.Length of the flower that has a Sepal.Length of 7.0 and Species == versicolor in every one of those four tibbles.

I can do this hardcoded with:

list_all[['iris_a']][51,3] <- list_all[['iris_a']][51,3] + list_all[['iris_a']][77,3]
list_all[['iris_b']][51,3] <- list_all[['iris_b']][51,3] + list_all[['iris_b']][77,3]
list_all[['iris_c']][51,3] <- list_all[['iris_c']][51,3] + list_all[['iris_c']][77,3]
list_all[['iris_d']][51,3] <- list_all[['iris_d']][51,3] + list_all[['iris_d']][77,3]

but trying to grab the value with something like

list_all[['iris_a']]['Sepal.Length' == 7.0 & 'Species' == 'versicolor', 'Petal.Width']

results in numeric(0).

I'm thankfull for any advice!

Upvotes: 0

Views: 39

Answers (2)

d-math
d-math

Reputation: 61

Thanks Gregor! I used this code following your advice, tried the %<>% that sindri recommended and it works now quite well.

list_all <- list_all %>%
  map(\(df) {
    df[df[["Sepal.Length"]] == 7.0 & df[["Species"]] == "versicolor", "Petal.Width"] %<>%
      add(df[df[["Sepal.Length"]] == 6.8 & df[["Species"]] == "versicolor", "Petal.Width"])
    df
  })

Upvotes: 0

Gregor Thomas
Gregor Thomas

Reputation: 146020

'Sepal.Length' == 7.0 is FALSE. Always. The string 'Sepal.Length' is not equal to the number 7. There's nothing in your code that tells base R that you intend Sepal.Length as a column name. (And similarly for 'Species' == 'versicolor'.)

You can get it like this:

list_all[['iris_a']][
  list_all[['iris_a']][['Sepal.Length']] == 7.0 & 
    list_all[['iris_a']][['Species']] == 'versicolor',
  'Petal.Width']

I think an lapply might be much nicer if you're doing the same thing to every data frame in the list:

list_all <- lapply(list_all, \(df) {
  df[    ## cell to replace
    df[['Sepal.Length']] == 7.0 & 
        df[['Species']] == 'versicolor',
      'Petal.Width'
  ] <-
    ## first value to sum 
    df[
      df[['Sepal.Length']] == 7.0 & 
        df[['Species']] == 'versicolor',
      'Petal.Width'
    ] + df[  ## second value to sum
      df[['Sepal.Length']] == 6.8 & 
        df[['Species']] == 'versicolor',
      'Petal.Width'  
    ]
  ## return the modified df
  df
})

Upvotes: 3

Related Questions