0

假设我有一个大约 1M 行的表格,格式如下:

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

在支付年份大于或等于审查年份的情况下,将每个观测值设置为 NA 的有效方法是什么?特别是,我希望表格看起来像这样:

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

2 回答 2

0

我们创建一个“付费”(“pi”)列的索引,使用“pi”对列进行子集化,通过将“付费”列的列名中的年份子字符串与“付费”列的列名进行比较来创建逻辑值矩阵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.table set更有效率。从'paid'列名中获取年份子串names,转换为data.tablesetDT(df1)),循环遍历'pi'中的列和set满足'i'中条件的NA。

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)
}
于 2016-12-17T15:49:42.077 回答
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 的答案更容易阅读。

于 2016-12-17T18:17:04.923 回答