检查一个字符串是否是 R 中另一个字符串的子集
Check if a string is a subset in another string in R
下面的数据包括 ID
和 Code
(字符类型)
ID <- c(1,1,1,2,2,3,3,3, 4, 4)
Code <- c("0011100000", "0001100000", "1001100000", "1100000000",
"1000000000", "1000000000", "0100000000", "0010000000", "0010000001", "0010000001")
df <- data.frame(ID, Code)
我需要删除基于 Code
值模式的记录(在每个 ID 内),即:
对于每个 ID
,我们查看 Code
的值,然后删除属于其他行的子集的值。
例如,对于 ID
=1,第 2 行是第 1 行的子集,因此我们删除第 2 行。但是,第 3 行不是第 2 行或第 3 行的子集,因此我们保留它。
对于 ID
=2,第 5 行是第 4 行的子集,因此我们将其删除。
对于ID
=3个,都是不一样的,所以我们都保留了。
对于ID
=4,由于两条记录的Code
相同,则保留第一条。
这是结果的预期最终视图:
它不是那么漂亮,但是用连接检查每个组合就可以了。
转换为 data.table
library(data.table)
setDT(df)
制作一个行计数器,并识别每个字符串中的所有 1
位置并保存到列表中。
df[, rn := .I]
df[, ones := gregexpr("1", df$Code)]
将每个组与其自身合并,并比较行号不匹配的列表。然后保留列表子集所在的行号,并从原始数据中删除这些行。在重复的情况下,只删除重复的第一次。
df[
funion(
df[df, on=c("ID","rn>rn"), if(all(i.ones[[1]] %in% ones[[1]])) .(Code=i.Code), by=.EACHI][, -"rn"],
df[df, on=c("ID","rn<rn"), if(all(i.ones[[1]] %in% ones[[1]])) .(Code=i.Code), by=.EACHI][, -"rn"]
),
on=c("ID","Code"),
mult="first",
drop := 1
]
df[is.na(drop), -c("rn","ones","drop")]
# ID Code
#1: 1 0011100000
#2: 1 1001100000
#3: 2 1100000000
#4: 3 1000000000
#5: 3 0100000000
#6: 3 0010000000
#7: 4 0010000001
下面的数据包括 ID
和 Code
(字符类型)
ID <- c(1,1,1,2,2,3,3,3, 4, 4)
Code <- c("0011100000", "0001100000", "1001100000", "1100000000",
"1000000000", "1000000000", "0100000000", "0010000000", "0010000001", "0010000001")
df <- data.frame(ID, Code)
我需要删除基于 Code
值模式的记录(在每个 ID 内),即:
对于每个 ID
,我们查看 Code
的值,然后删除属于其他行的子集的值。
例如,对于 ID
=1,第 2 行是第 1 行的子集,因此我们删除第 2 行。但是,第 3 行不是第 2 行或第 3 行的子集,因此我们保留它。
对于 ID
=2,第 5 行是第 4 行的子集,因此我们将其删除。
对于ID
=3个,都是不一样的,所以我们都保留了。
对于ID
=4,由于两条记录的Code
相同,则保留第一条。
这是结果的预期最终视图:
它不是那么漂亮,但是用连接检查每个组合就可以了。
转换为 data.table
library(data.table)
setDT(df)
制作一个行计数器,并识别每个字符串中的所有 1
位置并保存到列表中。
df[, rn := .I]
df[, ones := gregexpr("1", df$Code)]
将每个组与其自身合并,并比较行号不匹配的列表。然后保留列表子集所在的行号,并从原始数据中删除这些行。在重复的情况下,只删除重复的第一次。
df[
funion(
df[df, on=c("ID","rn>rn"), if(all(i.ones[[1]] %in% ones[[1]])) .(Code=i.Code), by=.EACHI][, -"rn"],
df[df, on=c("ID","rn<rn"), if(all(i.ones[[1]] %in% ones[[1]])) .(Code=i.Code), by=.EACHI][, -"rn"]
),
on=c("ID","Code"),
mult="first",
drop := 1
]
df[is.na(drop), -c("rn","ones","drop")]
# ID Code
#1: 1 0011100000
#2: 1 1001100000
#3: 2 1100000000
#4: 3 1000000000
#5: 3 0100000000
#6: 3 0010000000
#7: 4 0010000001