我的问题是提高代码的效率/优雅。我有一份药物清单。我想确定以C09和C10开头的药物。如果一个人有这些药物,我想给他们一个二元指标(1 =是,0 =否)他们是否有这些药物。二进制指示符将位于同一数据框中名为“statins”的新列中。我使用这篇文章作为指南:What's the R equivalent of SQL's LIKE 'description%' statement?。
这是我所做的;
names<-c("tom", "mary", "mary", "john", "tom", "john", "mary", "tom", "mary", "tom", "john")
drugs<-c("C10AA05", "C09AA03", "C10AA07", "A02BC01", "C10AA05", "C09AA03", "A02BC01", "C10AA05", "C10AA07", "C07AB03", "N02AA01")
df<-data.frame(names, drugs)
df
names drugs
1 tom C10AA05
2 mary C09AA03
3 mary C10AA07
4 john A02BC01
5 tom C10AA05
6 john C09AA03
7 mary A02BC01
8 tom C10AA05
9 mary C10AA07
10 tom C07AB03
11 john N02AA01
ptn = '^C10.*?'
get_statin = grep(ptn, df$drugs, perl=T)
stats<-df[get_statin,]
names drugs
1 tom C10AA05
3 mary C10AA07
5 tom C10AA05
8 tom C10AA05
9 mary C10AA07
ptn2='^C09.*?'
get_other=grep(ptn2, df$drugs, perl=T)
other<-df[get_other,]
other
names drugs
2 mary C09AA03
6 john C09AA03
df$statins=ifelse(df$drugs %in% stats$drugs,1,0)
df
names drugs statins
1 tom C10AA05 1
2 mary C09AA03 0
3 mary C10AA07 1
4 john A02BC01 0
5 tom C10AA05 1
6 john C09AA03 0
7 mary A02BC01 0
8 tom C10AA05 1
9 mary C10AA07 1
10 tom C07AB03 0
11 john N02AA01 0
df$statins=ifelse(df$drugs %in% other$drugs,1,df$statins)
df
names drugs statins
1 tom C10AA05 1
2 mary C09AA03 1
3 mary C10AA07 1
4 john A02BC01 0
5 tom C10AA05 1
6 john C09AA03 1
7 mary A02BC01 0
8 tom C10AA05 1
9 mary C10AA07 1
10 tom C07AB03 0
11 john N02AA01 0
所以,我可以得到我想要的东西 - 但我觉得可能有更好,更好的方法来做到这一点,并希望在此提供任何指导。一个明显的解决方案,我可以感觉你们都在屏幕上大喊大叫,只是使用'^ C'作为模式 - 因此可以捕获所有以C开头的药物。我将无法在主要分析中做到这一点,因为'在某些情况下,C'会捕捉到我不想要的东西,所以我需要尽量缩小它。
答案 0 :(得分:4)
你走了:
transform(df, statins=as.numeric(grepl('^C(10|09)', drugs)))