基本问题描述:
设df
为数据帧,df_match
为单行数据帧。在
我想对df
进行子集化,以便只保留其非NA值包含在df_match
的非NA值中的行。在
一个最小的例子:
df <- data.frame(A = c("a1", "a1", "a2", NA, "a1", "a1"),
B = c(NA,"b1", "b1", "b2", "b1",NA),
C = c(NA,NA,NA,NA,"c1","c1"),
D = c(NA,NA,NA,NA,"d1","d1"),
stringsAsFactors = FALSE)
# column D is not nessecary I imputed it to get a data frame when applying is.na() below
df_match <- data.frame(A= "a1",
B = "b1",
C = NA,
D = NA,
stringsAsFactors = FALSE)
A B C D
1 a1 <NA> <NA> <NA>
2 a1 b1 <NA> <NA>
3 a2 b1 <NA> <NA>
4 <NA> b2 <NA> <NA>
5 a1 b1 c1 d1
6 a1 <NA> c1 d1
> df_match
A B C D
1 a1 b1 NA NA
在最小的例子中,只有df
的前两行是正确的w.r.t.“部分匹配”。在
第3行和第4行在a列或B列中输入错误
第5个和第6个在df_match
中不支持的列中包含一个值(即在df\u match中具有非NA值的列)。在
A B C D
1 a2 b1 <NA> <NA>
2 <NA> b2 <NA> <NA>
3 a1 b1 c1 d1
4 a1 <NA> c1 d1
基本思路:
将df
的每一行与df_match
匹配,并将结果存储到一个布尔矩阵M
。在
然后创建一个按行号索引的布尔向量,如下所示:TRUE if
1)在M
上支持df_match
的列(即在dfˉmatch中具有非NA值的列)不包含false。在
2)在df_match
中不支持的M
列不包含TRUE
我目前对最小示例的解决方案:
df <- data.frame(A = c("a1", "a1", "a2", NA, "a1", "a1"),
B = c(NA,"b1", "b1", "b2", "b1",NA),
C = c(NA,NA,NA,NA,"c1","c1"),
D = c(NA,NA,NA,NA,"d1","d1"),
stringsAsFactors = FALSE)
# column D is not nessecary I imputed it to get a data frame when applying is.na() below
df_match <- data.frame(A= "a1",
B = "b1",
C = NA,
D = NA,
stringsAsFactors = FALSE)
library(dplyr)
# create a boolean vector for condition 2
not_matchable <- names(df_match)[is.na(df_match)]
bol_no_matchable <- df %>%
select(one_of(not_matchable)) %>%
is.na() %>%
apply(X = ., MARGIN = 1, any)
# create a boolean vector for condition 1
matchable <- names(df_match)[!is.na(df_match)]
bol_matchable <- sapply(1:nrow(df), function(row)
{
df[row,matchable] != df_match[,matchable]
}) %>%
apply(X = ., MARGIN = 2, FUN = any)
bol_matchable[is.na(bol_matchable)] <- FALSE
# filter the results
df <- df %>%
filter(!bol_matchable & bol_no_matchable)
问题:
问题:
在应用程序中,数据框df
有一个列X
,其中df
可以有df_match
之外的值。(见下文)
应用基本最小示例中的逻辑,我当前的解决方案如下:
df <- data.frame(A = c("a1", "a1", "a2", NA, "a1", "a1"),
B = c(NA,"b1", "b1", "b2", "b1",NA),
C = c("c2",NA,"c1",NA,"c1","c1"),
D = c(NA,"d2","d2","d2","d1","d1"),
X = c("C","D","C","D","D","C"),
stringsAsFactors = FALSE)
bol <- sapply(1:nrow(df), function(x)
{
# determine value in column X
X <- pull(df[x,], "X")
not_matchable <- setdiff(matchable, X)
# create boolean vector for condition 1)
bol_no_matchable <- df[x,] %>%
select(one_of(not_matchable)) %>%
is.na() %>%
all()
# create boolean vector for condition 2)
bol_matchable <- {df[x,not_matchable] != df_match[,not_matchable]}
bol_matchable[is.na(bol_matchable)] <- FALSE
bol_matchable <- any(bol_matchable)
# combine both conditions
bol <- !bol_matchable & bol_no_matchable
})
上面的代码没有我想要的那么快。因为我想将这个“函数”应用到一个数据帧df
,其中有~50m行和100+列,用于任意数据帧df_match
。在
因此,欢迎对不同方法的任何建议/想法以及对子分组的评论。在
您可以在}的列上}的对应元素是
df
和{Map
,如果{NA
或等于df_match
的元素,则为每一列对返回一个元素为TRUE
的向量。然后选择TRUE
的数目(由rowSums
生成)等于列数的行(即所有列要么匹配要么都是NA)。在注意:如果}输出的相应向量元素将是}时,它与
df_match
值是NA
,而df
值是非NA
,则{NA
,当与na.rm = TRUE
一起使用{FALSE
等价相关问题 更多 >
编程相关推荐