Вычтите первую строку в столбце из себя и все строки в этом столбце, для всех столбцов, кроме одного, в R

#r #dplyr

#r #dplyr

Вопрос:

У меня есть таблица, в которой первый столбец — это временные точки (например, 0 мин, 10 мин и т.д.), А каждый другой столбец — это разные тесты, причем каждая строка имеет измерение в каждый момент времени. (Для микробиологов здесь: кривые роста бактерий в 96-луночном планшете.) Я хочу выполнить коррекцию фона путем вычитания измерения времени 0 для каждого столбца из него самого и всех остальных в столбце, так что в момент времени 0 каждое измерение равно 0. Однако столбец time должен быть неизменным.

 > input
time    A1  A2  A3
0       1   1   2
10      2   3   3
20      3   5   4
30      4   7   5

>output
time    A1  A2  A3
0       0   0   0
10      1   2   1
20      2   4   2
30      3   6   3
 

Я пробовал df$A1 = df$A1 - df$A1[1] , и хотя это работает, у меня 96 столбцов, и это было бы утомительно.

Ответ №1:

Используя dplyr , вы могли бы сделать :

 library(dplyr)
input <- input %>% mutate(across(A1:A3, ~. - .[time == 0]))
input

#  time A1 A2 A3
#1    0  0  0  0
#2   10  1  2  1
#3   20  2  4  2
#4   30  3  6  3
 

В базе R вы можете использовать sweep :

 input[-1] <- sweep(input[-1], 2, unlist(input[input$time == 0, -1]), `-`)
 

данные

 input <- structure(list(time = c(0L, 10L, 20L, 30L), A1 = 1:4, A2 = c(1L, 
3L, 5L, 7L), A3 = 2:5), class = "data.frame", row.names = c(NA, -4L))
 

Ответ №2:

Мы можем использовать base R путем репликации с col , чтобы сделать длины одинаковыми перед выполнением вычитания

 input[-1] <- input[-1] - input[-1][input$time == 0][row(input[-1])]
input[-1]
#  A1 A2 A3
#1  0  0  1
#2  0  1  1
#3  0  2  1
#4  0  3  1
 

данные

 input <- structure(list(time = c(0L, 10L, 20L, 30L), A1 = 1:4, A2 = c(1L, 
3L, 5L, 7L), A3 = 2:5), class = "data.frame", row.names = c(NA, -4L))