2016-12-17 4 views
0

Предположим, у меня есть таблица около 1M строк в следующем формате:R редактирование dataframe на основе значения столбца

id paid_2000 paid_2001 paid_2002 paid_2003 censor_yr 
1 10   20   10   20   2001 
2 15   25   15   15   2003 

Что бы быть эффективным способом, чтобы установить каждое наблюдение в НС, где оплаченный год больше, чем или равна году цензора? В частности, я хотел бы таблицы выглядеть следующим образом:

id paid_2000 paid_2001 paid_2002 paid_2003 censor_yr 
1 10   NA   NA   NA   2001 
2 15   25   15   NA   2003 

ответ

0

Использование dplyr:

library(dplyr) 
df %>% 
    gather(paid_yr, value, grep("paid", names(.))) %>% 
    mutate(value = ifelse(as.numeric(gsub(".*_", "", paid_yr)) >= censor_yr, 
         NA, value)) %>% 
    spread(paid_yr, value) 

%>% select Бросок цепи в нижней части, чтобы переместить censor_yr назад к концу.

Может объяснять, как это работает, если вы хотите. Может быть, может быть, легче читать, чем ответы akrun.

0

Мы создаем индекс столбцов, «оплаченные» («пи»), подмножество столбцов, используя «пи», создать матрицу логических значения, сравнивая подстроку года с именами столбцов «платного» столбца с столбцом «censor_yr» и присваивая ему значение NA.

pi <- grep("paid", names(df1)) 
df1[pi][matrix(as.numeric(sub(".*_", "", names(df1)[pi]))[col(df1[pi])] >= 
         df1$censor_yr, nrow=2)] <- NA 
df1 
# id paid_2000 paid_2001 paid_2002 paid_2003 censor_yr 
#1 1  10  NA  NA  NA  2001 
#2 2  15  25  15  NA  2003 

Или мы можем сделать это в data.tableset, который был бы более эффективным. Получите подстроку года из names «платных» имен столбцов, конвертируйте в data.table (setDT(df1)), проведите по столбцам в «pi» и set значениям NA, которые соответствуют условию в «i».

library(data.table) 
nm1 <- as.numeric(sub(".*_", "", names(df1)[pi])) 
setDT(df1) 
for(j in seq_along(pi)){ 
    set(df1, i = which(nm1[j] >= df1$censor_yr), j= pi[j], value = NA) 
} 
Смежные вопросы