[英]Finding matching values in two vectors of different lengths in R
我有两个带有物种名称的向量,它们遵循两种不同的方法。 有些名称相同,有些名称不同,并且两者的排序方式不同。 一个例子:列表 1: c(Homo sapiens sapiens, Homo sapiens neanderthalensis, Homo直立人,...,n) 列表 2: c(Homo直立人, Homo sapiens, Homo neanderthalensis,...,n+1)
我写 n 和 n+1 来表示这些列表有不同的长度。
我想创建一个由两个值组成的新列表:在两个向量(例如直立人)之间存在匹配的情况下,我希望列表 2 的名称位于列表中名称所在的位置1,或者如果列表 1 中的位置不匹配“0”。所以在这种情况下,这个新列表将是 newlist: c(0,0, Homo直立人,...)
为此,我编写了以下代码,但它不起作用。
data<-read.table("species.txt",sep="\t",header=TRUE)
list1<-as.vector(data$Species1)
list2<-as.vector(data$Species2)
newlist<-as.character(rep(0,length(list1)))
for (i in 1:length(list1)){
for (j in 1:length(list2)){
if(list1[i] == list2[j]){newlist[i]<- list2[j]}else {newlist[i]= 0}
}
}
我希望这很清楚。
谢谢你的帮助!
以这个可重现的例子为例:
set.seed(1)
list1 <- letters[1:10]
list1names
list2 <- letters[sample(1:10, 10)]
您可以使用ifelse
避免循环:
newlist <- ifelse(list1==list2, list2, 0)
问题是你没有声明newname
,你的意思是newlist
吗?
如果要使用循环,则只能使用一个循环而不是 2 个循环,因为length(list1)
= length(list2)
:
for (i in 1:length(list1)){
if(list1[i] == list2[i]){newlist[i]<- list2[i]}else {newlist[i]= 0}
}
一般来说,如果你想匹配向量中的元素,你可以像这样使用match
:
> list1
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
> list2
[1] "c" "d" "e" "g" "b" "h" "i" "f" "j" "a"
> match(list1, list2)
[1] 10 5 1 2 3 8 4 6 7 9
如您所见, match
获取list2
中元素的索引,这些索引等于list1
的元素。 如果您有另一个表data2
,并且您想从data2$list3
data$list1 中获取对应元素的 data2 中的列,这很有用,您可以使用:
data <- data.frame(list1, list2)
list3 <- list2
columntoget <- 1:length(list2)
data2 <- data.frame(list3, columntoget)
data$mynewcolumn <- data2$columntoget[match(data$list1, data2$list3)]
> data$mynewcolumn
[1] 10 5 1 2 3 8 4 6 7 9
我不完全确定我了解您想要实现的目标,但我认为这可以满足您的需求。
list1 <- c("Homo sapiens sapiens","Homo sapiens neanderthalensis","Homo erectus")
list2 <- c("Homo erectus","Homo sapiens","Homo neanderthalensis")
sapply(list1, function(x) { ifelse(x %in% list2, list2[which(list1 == x)], 0) } )
内部 for 循环使用newname[i]
,它应该是newlist[i]
。 使用您的代码,您可以使用0
或物种名称覆盖newlist[i]
条目j
次。 这可能不是您想要的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.