如何编写 R 函数来查找数据框中的特定条件
Posted
技术标签:
【中文标题】如何编写 R 函数来查找数据框中的特定条件【英文标题】:How to write R function to find a specific condition in a dataframe 【发布时间】:2017-09-08 14:10:01 【问题描述】:我有一个特定的问题,我正在尝试使用 R 在数据框中解决。以下是示例数据的列和几行:
我想编写一个函数来查找存在多个 FIPS 和多个 PROMO 的 ZIP。所以换句话说,ZIPS 与不同的 PROMO 交叉 FIPS。我不需要担心 COUNTY、FACTOR_X 和 FACTOR_Y,但我确实需要保留它们。
共有三种可能的促销级别(低、零、可变)。如果 ZIP 存在于多个 FIPS 中,并且 PROMO 在子集中不是不同的,则 STATUS 为 FAIL。但是,如果 ZIP 存在于多个 FIPS 中并且 PROMO 在子集中不同(相同),则 STATUS 为 PASS。
这里是一些示例输出
ZIP,ST_COUNTY,FIPS,FACTOR_X,FACTOR_Y,PROMO,STATUS
8520,NJ MERCER,34021,XXX,YYY,变量,失败
8520,NJ MIDDLESEX,34023,XXX,YYY,零,失败
8525,NJ XUNTERDON,34019,XXX,YYY,LOW,FAIL
8525,NJ MERCER,34021,XXX,YYY,变量,失败
8540,NJ MERCER,34021,XXX,YYY,变量,失败
8540,NJ MIDDLESEX,34023,XXX,YYY,零,失败
8540,NJ SOMERSET,34035,XXX,YYY,零,失败
8558,NJ XUNTERDON,34019,XXX,YYY,LOW,FAIL
8558,NJ MERCER,34021,XXX,YYY,变量,失败
8558,NJ SOMERSET,34035,XXX,YYY,零,失败
23117,VA GOOCXLAND,51075,XXX,YYY,零,失败
23117,VA LOUISA,51109,XXX,YYY,LOW,FAIL
23117,VA SPOTSYLVANIA,51177,XXX,YYY,LOW,FAIL
23117,VA SPOTSYLVANIA,51177,XXX,YYY,零,失败
78015,TX BEXAR,48029,XXX,YYY,零,失败
78015,TX BEXAR,48029,XXX,YYY,零,失败
78015,TX COMAL,48091,XXX,YYY,LOW,FAIL
78015,TX COMAL,48091,XXX,YYY,零,失败
78015,TX KENDALL,48259,XXX,YYY,LOW,FAIL
78015,TX KENDALL,48259,XXX,YYY,零,失败
1906,MA ESSEX,25009,XXX,YYY,LOW,PASS
1906,MA MIDDLESEX,25017,XXX,YYY,LOW,PASS
1906,马萨福克,25025,XXX,YYY,低,通过
16127,PA BUTLER,42019,XXX,YYY,零,通过
16127,PA 劳伦斯,42073,XXX,YYY,零,通过
16127,PA MERCER,42085,XXX,YYY,零,通过
16127,PA VENANGO,42121,XXX,YYY,零,通过
对于输出,我想将原始列和新的 STATUS 列拆分为两个文件。第一个文件是 ZIP_PASS,所有 STATUS == PASS,第二个文件是 ZIP_FAIL,所有 STATUS == FAIL
=======
【问题讨论】:
您应该明确提供与您的示例相对应的预期输出。详情:***.com/questions/5963269/… 感谢弗兰克的建议,按要求进行了编辑。 如果您将期望的 STATUS 列添加到示例数据中,将会有所帮助。前四行是否为 FAIL(因为它们都是 PROMO=LOW),而后四行是否为 PASS? 【参考方案1】:这行得通吗?
library(dplyr)
df2 <- df1 %>% group_by(ZIP) %>%
mutate(STATUS=c("PASS","FAIL")[(n_distinct(PROMO)==n())+1]) %>%
ungroup
df_pass <- filter(df2,STATUS=="PASS")
df_fail <- filter(df2,STATUS=="FAIL")
# # A tibble: 8 x 7
# # Groups: ZIP [4]
# ZIP ST_COUNTY FIPS FACTOR_X FACTOR_Y PROMO STATUS
# <int> <chr> <int> <chr> <chr> <chr> <chr>
# 1 1431 MA MIDDLESEX 25017 XXX YYY LOW PASS
# 2 1431 MA WORCESTER 25027 XXX YYY LOW PASS
# 3 1434 MA MIDDLESEX 25017 XXX YYY LOW PASS
# 4 1434 MA WORCESTER 25027 XXX YYY LOW PASS
# 5 4009 ME CUMBERLAND 23005 XXX YYY ZERO FAIL
# 6 4009 ME OXFORD 23017 XXX YYY LOW FAIL
# 7 4029 ME CUMBERLAND 23005 XXX YYY ZERO FAIL
# 8 4029 ME OXFORD 23017 XXX YYY LOW FAIL
数据
df1 <- read.table(text="ZIP,ST_COUNTY,FIPS,FACTOR_X,FACTOR_Y,PROMO
01431,MA MIDDLESEX,25017,XXX,YYY,LOW
01431,MA WORCESTER,25027,XXX,YYY,LOW
01434,MA MIDDLESEX,25017,XXX,YYY,LOW
01434,MA WORCESTER,25027,XXX,YYY,LOW
04009,ME CUMBERLAND,23005,XXX,YYY,ZERO
04009,ME OXFORD,23017,XXX,YYY,LOW
04029,ME CUMBERLAND,23005,XXX,YYY,ZERO
04029,ME OXFORD,23017,XXX,YYY,LOW",sep=",",header=T,stringsAsFactors=F)
【讨论】:
这太棒了!创建两个表并将其拆分可能只是 STATUS 上的过滤器,对吗? 是的,这些是表df_pass
和df_fail
:)
为了安全起见,我在第一个查询末尾添加了 ungroup
语句
嘿弹涂鱼,我更新了这个问题来寻找三个级别的 PROMO。您提供的示例适用于两个级别,但不适用于三个级别。有什么建议吗?
也许是(n_distinct(PROMO) >1)
而不是(n_distinct(PROMO)==n())
?以上是关于如何编写 R 函数来查找数据框中的特定条件的主要内容,如果未能解决你的问题,请参考以下文章