Find rows in a data frame that match a list of values within an error and return the whole row

I think I understand what you want: for each point in experi, you want to find all the rows in df where masses is close enough (under a certain tolerance). The result should have one set of rows for each entry in experi, or a single row full of NA if no row in df is close enough.

I think this code would do what you want:

# define inputs
[...]
df<- data.frame(masses, names)
experi <-c(1400,163.6,262.1,42.6)
tolerance <- 0.5

# define a function to find the rows in df that match a given experi point
find_matching_rows <- function(exp){
    res <- df[abs(df$masses - exp) <= tolerance, ]
    
    if(nrow(res) == 0){
      return(data.frame(experi = exp,
                        masses = NA_real_,
                        names = NA_character_))
    }
    
    # add the experi value and reorder columns
    res$experi <- rep(exp, nrow(res))
    res[, c("experi", "masses", "names")]
}

# find matching rows for each value in experi
res_list <- lapply(experi,
                   find_matching_rows)

# we have a list, assemble as a dataframe
do.call(rbind, res_list)
#>     experi masses            names
#> 1   1400.0     NA             <NA>
#> 486  163.6 164.05  1 ACN 1 M 1 Na+
#> 507  163.6 164.05  2 ACN 2 M 2 Na+
#> 528  163.6 164.05  3 ACN 3 M 3 Na+
#> 247  262.1 262.05 1 ACN 2 MAc 1 H+
#> 11    42.6     NA             <NA>

Created on 2023-08-22 with reprex v2.0.2

2 Likes