how to divide rows by another row

Hello, lovely R Community,

I need your help again!

I have two rows in the table and I am trying to divide the first row values by the second rows. Sound simple but I cannot get my desired result. I can easily export in excel and do it but I'd like to learn this in R.

Thank you so much

My sample data

sample <- tibble::tribble(
          ~T, ~minus.5, ~minus.4, ~minus.3, ~minus.2, ~minus.1, ~Zero, ~plus.1, ~plus.2, ~plus.3, ~plus.4, ~plus.5, ~plus.6,
     "Blood",    432.7,    723.9,    623.5,      861,   1322.5,  2389,  1335.9,   518.8,   601.9,   503.1,   622.9,   420.1,
  "Patinets",       33,       39,       36,       39,       45,    62,      54,      48,      47,      39,      39,      36
  )

My desired result

desired_result <- tibble::tribble(
                    ~T,    ~minus.5,    ~minus.4,    ~minus.3,    ~minus.2,    ~minus.1,       ~Zero,     ~plus.1,     ~plus.2,     ~plus.3, ~plus.4,     ~plus.5,     ~plus.6,
  "Blood_div_patients", 13.11212121, 18.56153846, 17.31944444, 22.07692308, 29.38888889, 38.53225806, 24.73888889, 10.80833333, 12.80638298,    12.9, 15.97179487, 11.66944444
  )
``

You can get the numeric result with the code below and then add a T column.

sample <- tibble::tribble(
  ~T, ~minus.5, ~minus.4, ~minus.3, ~minus.2, ~minus.1, ~Zero, ~plus.1, ~plus.2, ~plus.3, ~plus.4, ~plus.5, ~plus.6,
  "Blood",    432.7,    723.9,    623.5,      861,   1322.5,  2389,  1335.9,   518.8,   601.9,   503.1,   622.9,   420.1,
  "Patinets",       33,       39,       36,       39,       45,    62,      54,      48,      47,      39,      39,      36
)
sample[1,-1]/sample[2,-1]
#>    minus.5  minus.4  minus.3  minus.2  minus.1     Zero   plus.1   plus.2
#> 1 13.11212 18.56154 17.31944 22.07692 29.38889 38.53226 24.73889 10.80833
#>     plus.3 plus.4   plus.5   plus.6
#> 1 12.80638   12.9 15.97179 11.66944

Created on 2020-02-17 by the reprex package (v0.3.0)

3 Likes

I'll add a gloss to @FJCC's answer.

The sample object is a tibble flavor of a data frame. Each row is a vector of values. Both of those vectors begin with a character entry.

"Blood"/"Patients"
#> Error in "Blood"/"Patients": non-numeric argument to binary operator

Created on 2020-02-17 by the reprex package (v0.3.0)

It's hard to divide one character string by another.

That's the reason for the subsetting sample[1,-1] which says take the first row, except for the first column, and sample[2,-1], the same for the second.

1 Like

I like it! Thats a good pick up.

How would you have done it if it was all numeric using dplyr?

Here is one way by tidying the data in another shape

sample <- tibble::tribble(
  ~T, ~minus.5, ~minus.4, ~minus.3, ~minus.2, ~minus.1, ~Zero, ~plus.1, ~plus.2, ~plus.3, ~plus.4, ~plus.5, ~plus.6,
  "Blood",    432.7,    723.9,    623.5,      861,   1322.5,  2389,  1335.9,   518.8,   601.9,   503.1,   622.9,   420.1,
  "Patients",       33,       39,       36,       39,       45,    62,      54,      48,      47,      39,      39,      36
)

library(tidyverse)
#> Warning: le package 'tidyverse' a été compilé avec la version R 3.6.2

sample %>%
  pivot_longer(-T) %>%
  pivot_wider(name, names_from = T) %>%
  mutate(Blood_div_patients = Blood/Patients)
#> # A tibble: 12 x 4
#>    name    Blood Patients Blood_div_patients
#>    <chr>   <dbl>    <dbl>              <dbl>
#>  1 minus.5  433.       33               13.1
#>  2 minus.4  724.       39               18.6
#>  3 minus.3  624.       36               17.3
#>  4 minus.2  861        39               22.1
#>  5 minus.1 1322.       45               29.4
#>  6 Zero    2389        62               38.5
#>  7 plus.1  1336.       54               24.7
#>  8 plus.2   519.       48               10.8
#>  9 plus.3   602.       47               12.8
#> 10 plus.4   503.       39               12.9
#> 11 plus.5   623.       39               16.0
#> 12 plus.6   420.       36               11.7

Created on 2020-02-18 by the reprex package (v0.3.0.9001)

5 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.