在R

时间:2018-10-29 10:33:12

标签: r

我有两种具有两种不同物种名称的载体。有些名称相同,有些则不同,并且都以不同的方式排序。一个例子: 清单1:c(智人,智人尼安德特人,直立人,...,n) 清单2:c(直立人,智人,尼安德特人(...),n + 1)

我写n和n + 1表示这些列表的长度不同。

我想创建一个由两个值组成的新列表:如果两个向量(例如直立人)之间存在匹配,我想在名称的位置使用列表2的名称在列表1中,或者在列表1中的位置不匹配“ 0”。因此,在这种情况下,此新列表将是新列表:c(0,0,直立人,...)

为此,我编写了以下代码,但是它不起作用。

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}
}
}

我希望这很清楚。

感谢您的帮助!

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我不能完全确定我了解您要实现的目标,但是我认为这可以满足您的需求。

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) } )

答案 2 :(得分:0)

内部for循环使用newname[i],其中应为newlist[i]。 使用您的代码,您用newlist[i]或物种名称j覆盖0componentDidMount次。这可能不是您想要的。