基于某些参考点对数据框进行多次计算

Multiple calculations on a dataframe based on certain reference points

嗨,我对此有点陌生,但我想弄清楚如何在 R 上做到这一点。

我正在尝试将一堆数据集除以某些基准值,然后取它的 log(),但是数据非常大,除了使用 for 循环之外,我不知道还有什么其他方法可以处理它.

比如我有这样一个数据:

Name Reference Lap1 Lap2 Lap3 Lap4 Lap5
Craig attempt1 34 21 33 21 32
Craig attempt2 29 28 29 30 29
Craig attempt3 25 25 24 21 26
Craig attempt4 20 21 21 22 24
Jeff attempt1 43 41 44 40 41
Jeff attempt2 38 38 37 36 35
Jeff attempt3 33 32 31 29 34
Jeff attempt4 29 27 26 25 27

我想能把Craig中的attempt 1的每个部分都划分出来,除以其他Craig attempts,然后取log,以第一次attempt作为参考进行比较。但我也想为每个单独的专栏和 Jeff 做这个,所以最终结果变成:

Name Reference Lap1 Lap2 Lap3 Lap4 Lap5
Craig attempt1 log(34/34) log(21/21) log(33/33) log(21/21) log(32/32)
Craig attempt2 log(29/34) log(28/21) log(29/33) log(30/21) log(29/32)
Craig attempt3 log(25/34) log(25/21) log(24/33) log(21/21) log(26/32)
Craig attempt4 log(20/34) log(21/21) log(21/33) log(22/21) log(24/32)
Jeff attempt1 43 41 44 40 41
Jeff attempt2 38 38 37 36 35
Jeff attempt3 33 32 31 29 34
Jeff attempt4 29 27 26 25 27

我也会为 Jeff 做同样的事情,他对其他尝试的尝试 1 的参考也是如此。请记住,列数会更多,而且我会比其他人涉及的更多。

完成此计算的最佳方法是什么?

如果有帮助,我尝试添加一些起始代码。我不擅长抱歉。

row1 <- c("Name", "Reference", "Lap1", "Lap2", "Lap3", "Lap4", "Lap5")
row2 <- c("Craig", "attempt1", 34, 21, 33, 21, 32)
row3 <- c("Craig", "attempt2", 29, 28, 29, 30, 29)
row4 <- c("Craig", "attempt3", 25, 25, 24, 21, 26)
row5 <- c("Craig", "attempt4", 20, 21, 21, 22, 24)
row6 <- c("Jeff", "attempt1", 43, 41, 44, 40, 41)
row7 <- c("Jeff", "attempt2", 38, 38, 37, 36, 35)
row8 <- c("Jeff", "attempt3", 33, 32, 31, 29, 34)
row9 <- c("Jeff", "attempt4", 29, 27, 26, 25, 27)
df <- t(data.frame(row1, row2, row3, row4, row5, row6, row7, row8, row9))

这是一种方法,使用 dplyr::group_by 分别为每个 Name 进行计算,并使用 dplyr::across 将计算应用于所有以“lap”开头的列。末尾的有趣位 ~log(.x/first(.x)) 意味着对于我们指定的每一列,我们要应用一个公式,该公式采用值 (.x) 并将其除以组中的第一个值 (first(.x)) 然后取该比率的对数。

library(dplyr)
df %>%
  group_by(Name) %>%
  mutate(across(starts_with("lap"), ~log(.x/first(.x)))) %>%
  ungroup()

或者,如果您的数据尚未对每个名称按 attempt1 排序,您可以换行:

...
mutate(across(starts_with("lap"), ~log(.x/.x[Reference == "attempt1"]))) %>%
...

或者如果您要操作的列有其他名称,但您知道它们是(或不是)哪一列#,您可以根据位置计算它们:

mutate(across(-(1:2), ~log(.x/first(.x)))) %>%    

结果

# A tibble: 8 × 7
  Name  Reference   Lap1    Lap2   Lap3    Lap4    Lap5
  <chr> <chr>      <dbl>   <dbl>  <dbl>   <dbl>   <dbl>
1 Craig attempt1   0      0       0      0       0     
2 Craig attempt2  -0.159  0.288  -0.129  0.357  -0.0984  # -0.159 = ln(29/34)
3 Craig attempt3  -0.307  0.174  -0.318  0      -0.208 
4 Craig attempt4  -0.531  0      -0.452  0.0465 -0.288 
5 Jeff  attempt1   0      0       0      0       0     
6 Jeff  attempt2  -0.124 -0.0760 -0.173 -0.105  -0.158 
7 Jeff  attempt3  -0.265 -0.248  -0.350 -0.322  -0.187 
8 Jeff  attempt4  -0.394 -0.418  -0.526 -0.470  -0.418

您的示例数据不是标准数据框,如果您指定列而不是行,将更容易处理。

df <- data.frame(
  stringsAsFactors = FALSE,
              Name = c("Craig","Craig","Craig",
                       "Craig","Jeff","Jeff","Jeff","Jeff"),
         Reference = c("attempt1","attempt2",
                       "attempt3","attempt4","attempt1","attempt2","attempt3",
                       "attempt4"),
              Lap1 = c(34L, 29L, 25L, 20L, 43L, 38L, 33L, 29L),
              Lap2 = c(21L, 28L, 25L, 21L, 41L, 38L, 32L, 27L),
              Lap3 = c(33L, 29L, 24L, 21L, 44L, 37L, 31L, 26L),
              Lap4 = c(21L, 30L, 21L, 22L, 40L, 36L, 29L, 25L),
              Lap5 = c(32L, 29L, 26L, 24L, 41L, 35L, 34L, 27L)
)