Процентное изменение для сгруппированных предметов в нескольких точках времени R - PullRequest
1 голос
/ 14 апреля 2020
id  timepoint  dv.a
1   baseline   100       
1   1min       105       
1   2min       90        
2   baseline   70        
2   1min       100       
2   2min       80        
3   baseline   80        
3   1min       80        
3   2min       90       

Я повторил данные измерений для данного субъекта в длинном формате, как указано выше. Я рассчитываю рассчитать процентное изменение относительно базовой линии для каждого предмета.

id  timepoint  dv   pct.chg 
1   baseline   100  100     
1   1min       105  105     
1   2min       90   90      
2   baseline   70   100     
2   1min       100  143     
2   2min       80   114     
3   baseline   80   100     
3   1min       80   100     
3   2min       90   113    

Ответы [ 4 ]

2 голосов
/ 14 апреля 2020
df <- expand.grid( time=c("baseline","1","2"), id=1:4)
df$dv <- sample(100,12)
df %>% group_by(id) %>%
 mutate(perc=dv*100/dv[time=="baseline"]) %>%
 ungroup()

Вы хотите что-то сделать для каждой группы 'id', так что это group_by, затем вам нужно создать новый столбец, чтобы было mutate. Эта новая переменная - это старая dv, масштабированная по значению, которое dv принимает на базовой линии - отсюда и внутренняя часть mutate. И, наконец, удалить группу, к которой вы применили.

0 голосов
/ 17 апреля 2020

Решение Base R: (при условии, что «baseline» всегда отображается как первая запись для группы)

data.frame(do.call("rbind", lapply(split(df, df$id), 
       function(x){x$pct.change <- x$dv/x$dv[1]; return(x)})), row.names = NULL)

Данные:

 df <- structure(
  list(
    id = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L),
    timepoint = c(
      "baseline",
      "1min",
      "2min",
      "baseline",
      "1min",
      "2min",
      "baseline",
      "1min",
      "2min"
    ),
    dv = c(100L, 105L, 90L, 70L, 100L, 80L, 80L, 80L, 90L)
  ),
  class = "data.frame",
  row.names = c(NA,-9L)
)
0 голосов
/ 14 апреля 2020

в Base R вы можете сделать это

for(i in 1:(NROW(df)/3)){
  df[1+3*(i-1),4] <- 100
  df[2+3*(i-1),4] <- df[2+3*(i-1),3]/df[1+3*(i-1),3]*100
  df[3+3*(i-1),4] <- df[3+3*(i-1),3]/df[1+3*(i-1),3]*100
}

colnames(df)[4] <- "pct.chg"

вывод:

> df
  id timepoint dv.a  pct.chg
1  1  baseline  100 100.0000
2  1      1min  105 105.0000
3  1      2min   90  90.0000
4  2  baseline   70 100.0000
5  2      1min  100 142.8571
6  2      2min   80 114.2857
7  3  baseline   80 100.0000
8  3      1min   80 100.0000
9  3      2min   90 112.5000
0 голосов
/ 14 апреля 2020

Попробуйте создать вспомогательный столбец, сгруппировать и организовать по нему. Затем используйте оконную функцию first в функции изменения:

df %>% mutate(clean_timepoint = str_remove(timepoint,"min") %>% if_else(. == "baseline", "0", .) %>% as.numeric()) %>% 
  group_by(id) %>% 
  arrange(id,clean_timepoint) %>% 
  mutate(pct.chg = (dv / first(dv)) * 100) %>% 
  select(-clean_timepoint)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...