У меня есть большой набор данных медицинских записей (20 миллионов строк). Я хочу создать новый столбец, который заполняется значением определенной строки внутри каждой группы.Для циклов: как избежать цикла, когда индекс используется для вызова нескольких разных значений столбцов?
Что выглядит Data Как
Данные выглядит следующим образом:
data <- data.frame(
ICUSTAY_ID = c(1,1,5,5,5,5,5,6,6,6,6),
DATA = c(0,0,0,0,1,0,0,0,0,1,0),
OFFSET = c(-20,0,-1500, 150, 155, 159, 300, -2000, 30, 100, 120),
AA_FIRST = c(NA, NA, NA, NA, 1, NA, NA, NA,NA,1,NA),
LABRESULT = c(4, 5, 3.5, 4.1, NA, 3.0, 5.5, 2.1, 2.5, NA, 3.5))
ID DATA OFFSET AA_FIRST LABRESULT
1 0 -20 NA 4.0
1 0 0 NA 5.0
5 0 -1500 NA 3.5
5 0 150 NA 4.1
5 1 155 1 NA
5 0 159 NA 3.0
5 0 300 NA 5.5
6 0 -2000 NA 2.1
6 0 30 NA 2.5
6 1 100 1 NA
6 0 120 NA 3.5
То, что я хочу, чтобы данные Похожим
Для каждой группы идентификаторов, я хочу, чтобы найти строку в этой группе, которая имеет AA_FIRST = 1 (там будет только одна из этих групп ID), найдите значение OFFSET для этой строки, а затем вставьте это значение OFFSET в новый столбец с именем refOFFSET для все строки идентификатора , Я хочу, чтобы результат выглядеть следующим образом:
ID DATA OFFSET AA_FIRST LABRESULT refOFFSET
1 0 -20 NA 4.0 NA
1 0 0 NA 5.0 NA
5 0 -1500 NA 3.5 155
5 0 150 NA 4.1 155
5 1 155 1 NA 155
5 0 159 NA 3.0 155
5 0 300 NA 5.5 155
6 0 -2000 NA 2.1 100
6 0 30 NA 2.5 100
6 1 100 1 NA 100
6 0 120 NA 3.5 100
группа идентификаторов 5 имеет AA_FIRST = 1, соответствующее смещение 155, так что колонна refOFFSET для всех строк с ID = 5 были заселенных 155.
Группа ID 6 имеет значение AA_FIRST = 1, соответствующее СМЕЩЕНИЮ 100, поэтому столбец refOFFSET для всех строк с ID = 6 был заполнен 100.
Для группы идентификаторов необязательно должно быть AA_FIRST = 1. Это относится к группе ID 1. Группа ID 1 не имеет AA_FIRST = 1, поэтому refOFFSET является NA.
Не все идентификационные значения могут существовать. Например, идентификаторы № 2, 3 и 4 не существуют.
Мой текущий подход
Мой код, чтобы сделать это прямо сейчас состоит из для петель и если/еще заявления. Я хотел бы придумать векторный или применить форму. Мой для цикл занимает слишком много времени с 20 миллионами строк.
data$refOFFSET <- NA #initialize column called refOFFSET
for (i in 1:length(data$ID)){
if (!length(which(data$ID==(data$ID[i]) & data$AA_FIRST==1))) { #if it's integer0
next #go on to next i
}else{
tmpval <- data$OFFSET[which(data$ID==(data$ID[i]) & data$AA_FIRST==1)]}
data$refOFFSET[i] <- tmpval #create column whose value is equal to the reference OFFSET for each ID (i.e. the OFFSET where AA_FIRST=1)
}
Вопрос
Кто-нибудь знает, как писать код выше в Векторизованных или применить форму? Все, что может ускорить вычисление? Спасибо!
Редактировать: мои воспроизводимые примеры данных и отображаемые исходные данные были немного разными. Я исправил это.
Вы используете какую-то базу данных, такую как SQL-Server? Потому что, если вы это сделаете, было бы намного проще – MVCNoob
Да, я мог бы вернуться и повторно извлечь данные на SQL-сервере. Вышеупомянутые столбцы уже взяты из нескольких разных слияний таблиц, и как DATA, так и AA_FIRST исходят из вычислений, выполненных в R. Я думаю, что было бы проще попытаться работать с данными в R, чтобы избежать повторного выполнения этих вычислений в SQL, но если нет никакого хорошего способа сделать это в R, тогда я определенно был бы открыт для подхода SQL. Благодаря! –