【问题标题】:R editing dataframe based on column valueR根据列值编辑数据框
【发布时间】:2016-12-17 15:45:11
【问题描述】:
假设我有一个大约 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
【问题讨论】:
标签:
r
data-science
data-scrubbing
【解决方案1】:
使用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 的答案更容易阅读。
【解决方案2】:
我们创建一个“付费”(“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.table(setDT(df1)),遍历'pi'和set中的列,将满足'中条件的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)
}