Найти значение для каждого предмета и сохранить как новую таблицу - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть фрейм данных с данными в длинном формате следующим образом

ID Frame.No ROI.No Flux.med
01 1        1      78
01 1        2      76
01 2        1      80
01 2        2      80
01 3        1      89
01 3        2      80
27 1        1      60
27 1        2      68
27 4        1      80
27 4        2      89

Для каждого «идентификатора» я хочу получить первый и максимальный Flux.med для ROI 1 и 2 и поместить все это в новый кадр данных. Если у меня есть фрейм данных только с одним субъектом (например, ID 01), я могу определить нужные мне значения Flux.med, используя следующий код:

ROI1.baseline <-  mydata %>%
    filter(ROI.No == "ROI 1" & Frame.No == min(Frame.No))%>%   
  select(Flux.Med)

ROI1.max <-  mydata%>%
     filter(ROI.No == "ROI 1")%>%
  filter (Flux.Med == max(Flux.Med))%>%
  select(Flux.Med)

ROI2.baseline <-  mydata%>%
  filter(ROI.No == "ROI 2" & Frame.No == min(Frame.No))%>%
  select(Flux.Med)

ROI.max <-  mydata%>%
   filter(ROI.No == "ROI 2")%>%
  filter (Flux.Med == max(Flux.Med))%>%
  select(Flux.Med)

Но мне нужно сделать это для каждого идентификатора и сохранить результаты в кадре данных.

Могу ли я сделать это с for l oop?

Ответы [ 3 ]

1 голос
/ 08 апреля 2020

Мы можем использовать data.table

library(data.table)
setDT(df1)[, .(first_flux = first(Flux.med), 
         max_flux = max(Flux.med)), .(ID, ROI.No)]

данные

df1 <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 27L, 27L, 27L, 
27L), Frame.No = c(1L, 1L, 2L, 2L, 3L, 3L, 1L, 1L, 4L, 4L), ROI.No = c(1L, 
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), Flux.med = c(78L, 76L, 80L, 
80L, 89L, 80L, 60L, 68L, 80L, 89L)), class = "data.frame", 
row.names = c(NA,-10L))
1 голос
/ 08 апреля 2020

Мы можем получить первое и max значение в каждом ID и ROI.No.

library(dplyr)

mydata %>%
  group_by(ID, ROI.No) %>%
  summarise(first_flux = first(Flux.med), 
             max_flux = max(Flux.med))

#    ID ROI.No first_flux max_flux
#  <int>  <int>      <int>    <int>
#1     1      1         78       89
#2     1      2         76       80
#3    27      1         60       80
#4    27      2         68       89

Или используя aggregate:

aggregate(Flux.med~ID + ROI.No, mydata, function(x) c(first = x[1], max = max(x)))

данных

mydata <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 27L, 27L, 27L, 
27L), Frame.No = c(1L, 1L, 2L, 2L, 3L, 3L, 1L, 1L, 4L, 4L), ROI.No = c(1L, 
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), Flux.med = c(78L, 76L, 80L, 
80L, 89L, 80L, 60L, 68L, 80L, 89L)), class = "data.frame", row.names = c(NA,-10L))
0 голосов
/ 20 апреля 2020

Спасибо за предложения. Вот как я это сделал в итоге:

ROI1.baseline <-  ldi_data %>%
  group_by(ID)%>%
  filter(ROI.No == "ROI 1" & Frame.No == min(Frame.No))%>%   ###uses lowest number frame as baseline (not necessarily frame 1 if it was excluded)
  select(Flux.Med)%>%
  dplyr::rename(ROI1_baseline = Flux.Med)%>%
  as.data.frame(ROI1.baseline)

ROI1.max <-  ldi_data%>%
  group_by(ID)%>%
  filter(ROI.No == "ROI 1")%>%
  filter (Flux.Med == max(Flux.Med))%>%
  select(Flux.Med)%>%
  dplyr::rename(ROI1_max = Flux.Med)%>%
  as.data.frame(ROI1.max)

ROI2.baseline <-  ldi_data%>%
  group_by(ID)%>%
  filter(ROI.No == "ROI 2" & Frame.No == min(Frame.No))%>%
  select(Flux.Med)%>%
  dplyr::rename(ROI2_baseline = Flux.Med)%>%
  as.data.frame(ROI2.baseline)

ROI2.max <-  ldi_data%>%
  group_by(ID)%>%
  filter(ROI.No == "ROI 2")%>%
  filter (Flux.Med == max(Flux.Med))%>%
  select(Flux.Med)%>%
  dplyr::rename(ROI2_max = Flux.Med)%>%
  as.data.frame(ROI2.max)

summary <-   Reduce(merge, list(ROI1.baseline, ROI1.max, ROI2.baseline, ROI2.max))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...