Определить TimePoint на основе даты - PullRequest
0 голосов
/ 27 июня 2018

У меня есть набор данных, в который в разное время были взяты несколько образцов разных типов от одного и того же человека, который дал мне набор данных, который выглядит следующим образом

Patient       SampleType     Collection-Date
1               A              15-02-2001
1               B              15-02-2001
2               A              19-02-2001
2               B              19-02-2001
3               A              16-05-2001
3               B              16-05-2001
1               A              16-03-2001
1               B              16-03-2001
3               B              05-03-2001

Обратите внимание, что дата указывается в формате день-месяц-год. В R я хотел бы создать новую переменную, которую я могу использовать для определения того, к какому моменту времени относится каждый образец, чтобы получить следующий вывод.

Patient       SampleType        Collection-Date    TimePoint
    1               A              15-02-2001        T1
    1               B              15-02-2001        T1
    2               A              19-02-2001        T1
    2               B              19-02-2001        T1
    3               A              16-05-2001        T1
    3               B              16-05-2001        T1
    1               A              16-03-2001        T2
    1               B              16-03-2001        T2
    3               B              05-03-2001        T2

Я разработал, как это сделать, в основном используя следующий код:

#generate a key to connect Patients and samples
df<-mutate(df, Key=paste(df$Patient,df$SampleType, sep = "")
#Create a list of Keys
KeyList <- list(df$Key)
#Separate the original data frame based on Key
#Create new dataframes for all values of Key
for (i in unique(DateComp$Key)){
  nam<-paste("df", i, sep = ".")
  assign(nam, DateComp[DateComp$Key== i,])
}

Это генерирует уникальный фрейм данных для каждой комбинации типа пациент-образец Затем я могу создать желаемый результат, выполнив следующие действия:

df.1A[order(as.Date(1A$Collection-Date, format="%d%m%Y")),]
rownames(df.1A)= NULL
df.1A <- mutate(df.1A, TimePoint = paste("TP", row_number(),sep=""))

Это в основном создает желаемый результат для пациента 1, тип образца A, так как он читается

Patient     SampleType    Collection-Date    Key     TimePoint
1           A             15-02-2001         1A      TP1
1           A             16-03-2001         1A      TP2

Однако у меня есть две проблемы с этим подходом: 1) Я должен вручную написать код для каждого уникально созданного фрейма данных

(поэтому, если кто-нибудь может объяснить, как я могу сделать это, используя функцию lapply или аналогичную, я был бы очень признателен)

2) Если у Пациента есть только определенный тип образца для его второго посещения, тогда он будет помечен как момент времени 1, а не как момент времени 2 Кто-нибудь знает, как я мог бы переписать код, чтобы это не было проблемой? Заранее спасибо!

1 Ответ

0 голосов
/ 04 июля 2018

Если я правильно понимаю, ОП хочет подсчитать записи отдельно для каждой комбинации Patient и SampleType в порядке появления в df.

data.table имеет удобную функцию rowid() для этой цели. Может также использоваться в трубе dplyr:

library(dplyr)
df %>% 
  mutate(TimePoint = data.table::rowid(Patient, SampleType, prefix = "TP"))
  Patient SampleType Collection-Date TimePoint
1       1          A      15-02-2001       TP1
2       1          B      15-02-2001       TP1
3       2          A      19-02-2001       TP1
4       2          B      19-02-2001       TP1
5       3          A      16-05-2001       TP1
6       3          B      16-05-2001       TP1
7       1          A      16-03-2001       TP2
8       1          B      16-03-2001       TP2
9       3          B      05-03-2001       TP2

Это соответствует ожидаемому результату ОП. Однако я считаю, что это не правильный результат.

Более безопасный подход при заказе по дате

Подход, описанный выше, имеет большой недостаток: нумерация временных точек зависит от заданного порядка строк в df. Но порядок строк для Patient 3 и SampleType B не соответствует Collection-Date:

df %>% 
  mutate(TimePoint = data.table::rowid(Patient, SampleType, prefix = "TP")) %>% 
  arrange(Patient, SampleType, `Collection-Date`)
  Patient SampleType Collection-Date TimePoint
1       1          A      15-02-2001       TP1
2       1          A      16-03-2001       TP2
3       1          B      15-02-2001       TP1
4       1          B      16-03-2001       TP2
5       2          A      19-02-2001       TP1
6       2          B      19-02-2001       TP1
7       3          A      16-05-2001       TP1
8       3          B      05-03-2001       TP2
9       3          B      16-05-2001       TP1

Строка 8 помечена TP2, хотя дата сбора более ранняя, чем TP1 в строке 9. Я сомневаюсь, что это правильная и предполагаемая нумерация временных точек.

Итак, строки должны быть переупорядочены по дате сбора перед применением функции rowid().

Кроме того, мы можем исправить еще один недостаток. Collection-Date не является синтаксически допустимым именем и может вызвать проблемы с кодированием (если не экранировано).

Здесь мы переключаемся на data.table синтаксис, с которым я больше знаком:

library(data.table)
# coerce to data.table
setDT(df)
# make syntactically valid names
setnames(df, names(df), make.names(names(df)))
# convert character date to class Date
df[, Collection.Date := lubridate::dmy(Collection.Date)]
# order by Date and append rowid counts
df[order(Collection.Date), TimePoint := rowid(Patient, SampleType, prefix = "TP")][]
   Patient SampleType Collection.Date TimePoint
1:       1          A      2001-02-15       TP1
2:       1          B      2001-02-15       TP1
3:       2          A      2001-02-19       TP1
4:       2          B      2001-02-19       TP1
5:       3          A      2001-05-16       TP1
6:       3          B      2001-05-16       TP2
7:       1          A      2001-03-16       TP2
8:       1          B      2001-03-16       TP2
9:       3          B      2001-03-05       TP1

Обратите внимание, что строки df не были переставлены, но функция rowid() была применена в правильном порядке, поэтому строка 9 теперь правильно помечена как TP1 в соответствии с датой ее сбора.

Данные

library(data.table)
df <- fread(
  "Patient       SampleType     Collection-Date
1               A              15-02-2001
1               B              15-02-2001
2               A              19-02-2001
2               B              19-02-2001
3               A              16-05-2001
3               B              16-05-2001
1               A              16-03-2001
1               B              16-03-2001
3               B              05-03-2001",
  data.table = FALSE
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...