2014-10-22 3 views
1

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

structure(list(AccountNumber = 1:5, ActivationDate = c(201001L, 
201002L, 201001L, 201010L, 201008L), Payments_201001 = c(100L, 
NA, 2342L, NA, NA), Payments_201002 = c(200L, 100L, 235L, NA, 
NA), Payments_201003 = c(100L, 100L, 111L, NA, NA), Payments_201004 = c(100L, 
100L, 144L, NA, NA), Payments_201005 = c(150L, 100L, NA, NA, 
NA), Payments_201006 = c(150L, 100L, NA, NA, NA), Payments_201007 = c(NA, 
100L, NA, NA, NA), Payments_201008 = c(NA, 100L, NA, NA, 144L 
), Payments_201009 = c(NA, NA, NA, NA, 159L), Payments_201010 = c(NA, 
NA, NA, 100L, 100L)), .Names = c("AccountNumber", "ActivationDate", 
"Payments_201001", "Payments_201002", "Payments_201003", "Payments_201004", 
"Payments_201005", "Payments_201006", "Payments_201007", "Payments_201008", 
"Payments_201009", "Payments_201010"), class = "data.frame", row.names = c(NA, 
-5L)) 

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

Что я пытаюсь сделать, так это создать новый массив Payments1-Payments10, который соответствует учетным записям платежей в месяцах от 1 до 10, начиная с активации. В частности - Payments1 должна соответствовать сумме, поступающей из первого месяца после активации (DataRow 1 -> значение должно исходить от Payments_201002-> 200), Payments2 на сумму от 2-х месяцев после активации и т.д ...

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

single.shift<- function (x){ 
     r <- rle(is.na(x)) 
     if(!r$values[1]) return(x) 
     num <- r$length[1] 
     c(x[-1:-num], rep(NA, num)) 
} 
t(apply(x, 1, single.shift)) 

в моем конкретном случае не применяется в связи со спецификой данных (месяц активации также имеющие платежи, пробелы в истории и т.д.)

Если бы это был SAS, я бы сделал следующее: Создание 2 Массивы:

Array Pay1 Payments201001-Payments201010; 
Array Pay2 Payments1-Payments10; 

я бы индекс активации DATE и создать новый вар -> например, если ActivationDate = 201001, то IndexVar = 1, ActivationDate = 201003, то IndexVar = 3 и т.д.

Поскольку SAS работает на строках я могу затем использовать петли

do i = 1 to 10-IndexVar; /*(since for the 10th month there's no one month AFTER)*/ 
Pay2[i] = Pay1[IndexVar+i]; 
end; 

Я не в состоянии сделать это сейчас в R.

ответ

0

Вот как я решил бы это. Я вообще не использую ActivationDate, так как я полагаю, что он определяется первой записью, отличной от NA. Я также удаляю trailes NA с помощью удобной функции na.trim из пакета zoo.

payment_cumul <- apply(df[, -(1:2)], 1, function(x) 
{ 
    y <- na.trim(x, sides = "left") 
    y[is.na(y)] <- 0 
    cumsum(y) 
}) 

get_i_months <- function(i) 
{ 
    sapply(payment_cumul, function(x) { 
    z <- x[i] 
    if (is.na(z)) return(x[length(x)]) 
    z 
    }) 
} 
# payments for the first month since activation 
get_i_months(1) 
#Payments_201001 Payments_201002 Payments_201001 Payments_201010 Payments_201008 
#   100    100   2342    100    144 

# payments for 10 first months 
get_i_months(10) 
#Payments_201010 Payments_201010 Payments_201010 Payments_201010 Payments_201010 
#   800    700   2832    100    403 
+0

Hi tonytonov - спасибо, что ответит! Проблема двоякая: мне на самом деле не нужны кумулятивы, а нужно знать номинальную сумму платежа через месяц после активации, через 2 месяца после активации и т. Д. Но это не главная шоу-стоппер для меня. Реальная проблема заключается в том, что в течение некоторого месяца у меня есть платежи NA В месяце активации - поэтому удаление ведущих заготовок не работает для меня - я должен иметь возможность ссылаться на 1 месяц после активации, зная, что на самом деле дата активации. – Bullzeye

+0

Тогда я боюсь, что код будет значительно сложнее, так как вам придется разбирать дату. Хорошо, я мог бы пересмотреть это через некоторое время. – tonytonov

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