Search code examples
rmatrixapplyrows

applying a function across rows in dataframe


I have a dataset of approximate counts of birds of 5 species. I wrote a function to calculate the diversity of species using Broullions Index. My data looks like this and my function is written like this:

df <- data.frame(
sp1 = c(2, 3, 4, 5),         
sp2 = c(1, 6, 7, 2),
sp3 = c(1, 9, 4, 3),
sp4 = c(2, 2, 2, 4),
sp5 = c(3, 3, 2, 1),
treatment1 = c("A", "B", "C", "A"),
treatment2 = c("D", "E", "D", "E")
)

#write function that estimates Broullion's Index
Brillouin_Index <- function(x){  
  N <- sum(x)
 (log10(factorial(N)) - sum(log10(factorial(x)))) / N
}

df2 <- df %>%
   mutate(bindex = Brillon_Index(matrix(df[1:5,])

How do apply my function to calculate the Broullions Index across rows? I thought something like the above would work but no luck yet. The point would be to use the diversity index as the response variable in relation to treatment 1 and 2 which is why I'd like to sum across rows and get a single value across for each row for a new variable called bindex. Any help will be greatly appreciated. Best,


Solution

  • We can use rowwise to group by row

    library(dplyr)
    df <- df %>% 
      rowwise %>%
      mutate(bindex = Brillouin_Index(as.matrix(c_across(1:5)))) %>%
      ungroup
    

    -output

    df
    # A tibble: 4 x 8
    #    sp1   sp2   sp3   sp4   sp5 treatment1 treatment2 bindex
    #  <dbl> <dbl> <dbl> <dbl> <dbl> <chr>      <chr>       <dbl>
    #1     2     1     1     2     3 A          D           0.464
    #2     3     6     9     2     3 B          E           0.528
    #3     4     7     4     2     2 C          D           0.527
    #4     5     2     3     4     1 A          E           0.505
    

    Or use apply in base R

    df$bindex <- apply(df[1:5], 1, Brillouin_Index)
    df$bindex
    #[1] 0.4643946 0.5277420 0.5273780 0.5051951
    

    Or with dapply in collapse

    library(collapse
    df$bindex <- dapply(slt(df, 1:4), Brillouin_Index, MARGIN = 1)