循环通过与另一列相关联的列,以根据R中的两个匹配列来过滤特定的字符代码

holgip5t  于 2023-05-20  发布在  其他
关注(0)|答案(2)|浏览(324)

我有一个有1500万条记录的数据集。每条记录都有一个ID,然后有25列,每列中输入1到25个事件代码。这些事件代码列中的每一列在数据集中都有一个对应的列,其中包含原因代码。每个人都将至少有一个事件,但不是每个人都将所有25列填写。我在下面提供了一个小的示例数据集,只有3个事件列和3个原因列。
我尝试用R编写代码,检查每个事件列并查找特定的事件代码(例如,U78),然后如果它在事件列中找到该代码,则会查找相应的原因列以查找特定的原因代码(例如,3或Y)。如果相应的原因代码匹配,我希望在新的 Dataframe 中保留该记录。
在下面的示例数据中,它将查看ID为5的行,并看到Col_1具有U78,因此它将查看相应的原因列(Col_R_1),以获得“3”或“Y”。在这种情况下,它是一个3,所以我希望保持这个记录。
相比之下,ID 22的事件代码中有“U78”,但由于相应字段中的原因代码是“M”,因此我不希望保留该记录。ID 8没有U78事件,因此我也不希望保留该记录。
此示例的最终数据集将仅保留ID 5、6和343,因为它们都具有U78事件,其对应的原因代码为3或Y。
我可以使用25个case_when语句一次对一对列进行比较(基本上,如果Col_1 ==“U78”& Col_1_R ==“3”|Col_1_R“R”),然后在我生成的标志上应用过滤器,但我想知道是否有更有效的方法?
谢谢你。
示例数据集:

structure(list(ID = c(5, 6, 7, 8, 22, 343, 656, 595), Col_1 = c("U78", 
"D38", "T90", "T8", "U78", "G90", "G90", "Y88"), Col_2 = c("T90", 
"U78", NA, NA, NA, "T90", "B12", "T90"), Col_3 = c(NA, NA, NA, 
NA, NA, "U78", NA, NA), Col_R_1 = c("3", "M", "R", "M", "M", 
"3", "3", "Y"), Col_R_2 = c("M", "Y", NA, NA, NA, "M", "M", "M"
), Col_R_3 = c(NA, NA, NA, NA, NA, "Y", NA, NA)), row.names = c(NA, 
-8L), class = c("tbl_df", "tbl", "data.frame"))
qojgxg4l

qojgxg4l1#

我们可以使用mapply来迭代列对组:每个Col_#与其Col_R_#列配对。这里我将使用subset,尽管还有其他方法可以实现这一点。

fun <- function(col, rsn) col == "U78" & rsn %in% c("3", "Y")
mtx <- mapply(fun, 
              subset(quux, select=Col_1:Col_3),
              subset(quux, select=Col_R_1:Col_R_3))
mtx
#      Col_1 Col_2 Col_3
# [1,]  TRUE FALSE FALSE
# [2,] FALSE  TRUE FALSE
# [3,] FALSE FALSE FALSE
# [4,] FALSE FALSE FALSE
# [5,] FALSE FALSE FALSE
# [6,] FALSE FALSE  TRUE
# [7,] FALSE FALSE FALSE
# [8,] FALSE FALSE FALSE
quux[rowSums(mtx) > 0,]
# # A tibble: 3 × 7
#      ID Col_1 Col_2 Col_3 Col_R_1 Col_R_2 Col_R_3
#   <dbl> <chr> <chr> <chr> <chr>   <chr>   <chr>  
# 1     5 U78   T90   NA    3       M       NA     
# 2     6 D38   U78   NA    M       Y       NA     
# 3   343 G90   T90   U78   3       M       Y

mapply与函数fun的使用实际上是相同的:

fun(quux$Col_1, quux$Col_R_1)
fun(quux$Col_2, quux$Col_R_2)
fun(quux$Col_3, quux$Col_R_3)

由于我们使用的是mapply,它将这些向量简化为一个矩阵(我暂时存储为mtx)。

1bqhqjot

1bqhqjot2#

这是另一种方法。
1.将您的规则放在数据框架中(我添加了一个额外的规则来说明多个标志的使用)

flags = data.frame(e=c("T90", "U78", "U78"), r=c("R", "3", "Y"))

1.重新排列数据,并合并符合标志的行

library(data.table)
setDT(df)

df[dcast(
  melt(df,"ID",variable.name = "v")[
  ,`:=`(col=gsub("Col_(R_)?", "", v),v=fifelse(grepl("_R_",v),"r", "e"))],
  ID+col~v
)[flags, on=.(e,r), .(ID = unique(ID))], on=.(ID)]

输出:

ID  Col_1  Col_2  Col_3 Col_R_1 Col_R_2 Col_R_3
   <num> <char> <char> <char>  <char>  <char>  <char>
1:     7    T90   <NA>   <NA>       R    <NA>    <NA>
2:     5    U78    T90   <NA>       3       M    <NA>
3:     6    D38    U78   <NA>       M       Y    <NA>
4:   343    G90    T90    U78       3       M       Y

在我的示例中,flag假设相同的规则适用于不同的列对。即,如果U78出现的原因是3Y,或者如果事件T90出现的原因是R,并且这些标志适用于所有列。如果这些是特定于列的,只需将名为col的列添加到flags,以指定哪些原因/事件组合与哪些列对应。

相关问题