2016-01-18 3 views
0

Ищете способ заполнить вектор с новыми значениями, зависящими от значений внутри этого вектора и другой переменной в кадре данных. Вставьте пример того, как данные выглядят ниже.Условная серия Заполните R

PrsVar= c(rep(1,10),rep(2,7),rep(3,11)) 
IndVar = c(0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0) 
OutVar = c(1,1,1,1,2,2,2,3,3,3,1,1,1,1,2,2,2,1,1,1,1,2,2,2,2,3,3,3) 
exampdata <- cbind(PrsVar,IndVar,OutVar) 
exampdata <- as.data.frame(exampdata) 

> exampdata 
    PrsVar IndVar OutVar 
1  1  0  1 
2  1  0  1 
3  1  0  1 
4  1  1  1 
5  1  0  2 
6  1  0  2 
7  1  1  2 
8  1  0  3 
9  1  0  3 
10  1  0  3 
11  2  0  1 
12  2  0  1 
13  2  0  1 
14  2  1  1 
15  2  0  2 
16  2  0  2 
17  2  1  2 
18  3  0  1 
19  3  0  1 
20  3  0  1 
21  3  1  1 
22  3  0  2 
23  3  0  2 
24  3  0  2 
25  3  1  2 
26  3  0  3 
27  3  0  3 
28  3  0  3 

Это данные временного ряда, и каждая строка представляет собой человеко-день. PrsVar - это идентификатор для лица в исследовании, а IndVar - индикатор того, что эпизод закончился в этот день. Человек-день после этого представляет собой новый эпизод.

Я хотел бы создать переменную, которая выглядит как OutVar, используя только значения от PrsVar и IndVar. Эта новая переменная OutVar обозначает эпизод, в котором каждый человек-день находится, увеличивается на 1 и начинается с 1 для каждого нового человека.

Я мог бы запустить это через цикл, но мне нужен более эффективный код для работы с 3 000 000 + строк данных. Старался что-то использовать в dplyr или, может быть, mapply, но я в тупике. Размышление о решении этого было бы полезно для других и, несомненно, было бы полезно для меня снова в ближайшем будущем.

ответ

1

Немного некрасиво, но эта логика должна быть легко адаптирована к другим методам:

with(exampdata, 
    ave(IndVar, PrsVar, FUN=function(x) { 
    out <- rev(cumsum(rev(x))) 
    max(out) - out + 1 
    }) 
) 

# [1] 1 1 1 1 2 2 2 3 3 3 1 1 1 1 2 2 2 1 1 1 1 2 2 2 2 3 3 3 
+0

Спасибо, я закончил тем, что использовал это. Не думал об обратном, обратном, очень полезен. – ArcherT

3

Пакет data.table предлагает быстрый, эффективный и аккуратный способ сделать это. Все это делается по ссылке (не по значению, поэтому копирование не выполняется), поэтому миллионы строк не будут проблемой вообще (возможно, через минуту).

library(data.table) 
patient.data <- data.table(PrsVar = c(rep(1,10), rep(2,7), rep(3,11)), 
          IndVar = c(0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0), 
          OutVar = c(1,1,1,1,2,2,2,3,3,3,1,1,1,1,2,2,2,1,1,1,1,2,2,2,2,3,3,3)) 

Приращение счетчика эпизод EpVar на основе накопленной суммы IndVar (плюс 1). Это увеличивает счетчик в записи, где IndVar увеличивается (что слишком рано), поэтому сдвиньте запись вниз с shift, заменив недостающее значение на счетчик сброса (1). Это можно сделать groupwise с ключевым словом by.

patient.data[ , EpVar:=shift(1+cumsum(IndVar), fill=1), by=PrsVar] 
patient.data 
    PrsVar IndVar OutVar EpVar 
1:  1  0  1  1 
2:  1  0  1  1 
3:  1  0  1  1 
4:  1  1  1  1 
5:  1  0  2  2 
6:  1  0  2  2 
7:  1  1  2  2 
8:  1  0  3  3 
9:  1  0  3  3 
10:  1  0  3  3 
11:  2  0  1  1 
12:  2  0  1  1 
13:  2  0  1  1 
14:  2  1  1  1 
15:  2  0  2  2 
16:  2  0  2  2 
17:  2  1  2  2 
18:  3  0  1  1 
19:  3  0  1  1 
20:  3  0  1  1 
21:  3  1  1  1 
22:  3  0  2  2 
23:  3  0  2  2 
24:  3  0  2  2 
25:  3  1  2  2 
26:  3  0  3  3 
27:  3  0  3  3 
28:  3  0  3  3 
+0

Спасибо, я думал об использовании data.table, но не успел залезть в него, а dplyr на фреймах данных прошел довольно хорошо. – ArcherT

+0

Если вы хотите изучить 'data.table', курс DataCamp хорошо структурирован. 'dplyr' также работает и с data.tables. Улучшение скорости из-за копирования по ссылке является выдающимся и при использовании миллионов строк, что потенциально необходимо. В ответе 'dplyr' на' data.frame' моего ответа по-прежнему требуется 'data.table :: shift()', но более или менее одинаково; 'library (dplyr); data.frame (patient.data)%>% group_by (PrsVar)%>% mutate (EpVar = shift (1 + cumsum (IndVar), fill = 1)) ' –

Смежные вопросы