为什么R中的百分比%不能正确匹配?

时间:2018-05-23 10:29:03

标签: r

我是R.的新手。我创建了两个向量' a'和' b'在R.它们都包含相同的元素,但顺序不同。以下是2个向量的详细信息。

> str(a)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   369 obs. of  1 variable:
$ SKD_DOCUMENT_NO: chr  "A0000514011" "A0000514012" "A0000514013" "A0000514014" ...
> str(b)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   369 obs. of  1 variable:
$ SKD_DOCUMENT_NO: chr  "A0000648001" "A0000648050" "A0000648049" 
"A0000648048" ...

但是当我试图检查一个元素是否在向量中时,我得到了来自R的令人困惑的答案。

>'A0000648050' %in% a   #[1] FALSE 
>"A0000648050" %in% a   #[1] FALSE

但是当我尝试使用其他方法来检查元素是否在' a'。然后是以下结果:

> any(a == "A0000648050")       #[1] TRUE
> which(a == "A0000648050")     #[1] 115
> grep("A0000648050", a)        #[1] 1

Q1。我不明白为什么%in%失败。

Q2。找到' a'的所有元素的最简单方法是什么?向量存在于' b'的所有元素中。向量? (' a'的所有元素确实存在于' b。但是希望从R确认)。为什么以下2行给出不同的结果?

> a %in% b            #[1] FALSE
> setequal(a,b)       # TRUE

1 个答案:

答案 0 :(得分:0)

<强>%中%

来自?'%in%'

  

%in%目前被定义为&#34;%in%&#34; &lt; - function(x,table)match(x,   table,nomatch = 0)&gt; 0

     

因子,原始矢量和列表被转换为字符向量,和   然后x和表被强制转换为一个普通类型(两者中较晚的一个)   R的排序类型,逻辑&lt;整数&lt;数字&lt;复杂&lt;   匹配前的字符)如果不相容的长度是正的   强迫共同的类型。

在您的情况下atibbledata.framelist,因此在比较之前将其转换为字符的地方。

a <- tibble(SKD_DOCUMENT_NO =c("A0000514011","A0000514012","A0000514013","A0000514014"))
as.character(a)
# [1] "c(\"A0000514011\", \"A0000514012\", \"A0000514013\", \"A0000514014\")"

虽然这不直观,但会返回TRUE

"c(\"A0000514011\", \"A0000514012\", \"A0000514013\", \"A0000514014\")" %in% a

<强>任何

来自?any

...参数:

  

忽略零长度的其他对象,其余对象被强制转换为   逻辑无视任何阶级。

a == "A0000514012"
#      SKD_DOCUMENT_NO
# [1,]           FALSE
# [2,]            TRUE
# [3,]           FALSE
# [4,]           FALSE

当我们将其强制为逻辑时,会发生以下情况:

as.logical(a == "A0000514012")
# [1] FALSE  TRUE FALSE FALSE

因此any(a == "A0000514012")获得的输出是有意义的。

可以使用whichgrep

进行相同的练习

<强>溶液

解决方案是使用:

"A0000514012" %in% a$SKD_DOCUMENT_NO # to look into a precise column

"A0000514012" %in% unlist(a) # to look into all columns, equivalent to your solution with `any`

sapply(a,`%in%`,x = "A0000514012") # to look into individual columns separately