R语言如何比较类型结构不同的两个向量的元素匹配值
问题复现
执行以下代码时,intersect()返回空列表,无法得到预期的数值交集结果:
# fo为手动构造的数值型向量 fo <- c(1,3,6,7,8,9,10,11) fo # [1] 1 3 6 7 8 9 10 11 is.vector(fo) # [1] TRUE library(stringr) # fo2为字符串拆分得到的结果 fo2 <- str_split("1 3 6 7 8 10 11 13 14 15", " ") fo2 # [[1]] # [1] "1" "3" "6" "7" "8" "10" "11" "13" "14" "15" is.vector(fo2) # [1] TRUE intersect(fo,fo2) # list()
问题原因
结果不符合预期是两个问题叠加导致的:
stringr::str_split()默认返回列表结构:R中列表属于递归向量范畴,因此is.vector(fo2)会返回TRUE,容易造成误导。当前fo2是长度为1的列表,并非直接存储拆分结果的原子向量,输出中的[[1]]标记就对应列表的第一层元素,也就是真正需要的拆分内容。- 类型不匹配:就算提取出列表内的拆分结果,其存储类型是字符型(character),和
fo的数值型(numeric) 类型不一致,R的集合运算不会自动做跨类型值匹配,因此无法识别相同数值。
修复方案
先提取str_split()返回列表中的拆分结果,再将字符型数字转换为数值型,之后即可正常执行集合运算:
library(stringr) fo <- c(1,3,6,7,8,9,10,11) # 处理fo2:用[[1]]提取列表内的拆分结果,再转成数值型 fo2 <- as.numeric(str_split("1 3 6 7 8 10 11 13 14 15", " ")[[1]]) # 取交集 intersect(fo, fo2)
运行后得到正确交集结果:
[1] 1 3 6 7 8 10 11
如果不想依赖stringr第三方包,也可以用R基础函数实现相同效果:
fo <- c(1,3,6,7,8,9,10,11) # 基础R自带的strsplit函数逻辑和str_split一致,默认返回列表 fo2 <- as.numeric(strsplit("1 3 6 7 8 10 11 13 14 15", " ")[[1]]) intersect(fo, fo2)
内容的提问来源于stack exchange,提问作者Cheong Daniel
相关产品推荐
相关产品推荐

