【问题标题】:MATCH function in r [duplicate]r中的MATCH函数[重复]
【发布时间】:2016-12-15 18:02:11
【问题描述】:

有列表,第一个 (list1) 有 id、name、age,其他的 (list2,list3,..) 有 id 和测试值(唯一)。

列表 1:

id  age name    bio-test    
1   40  danny
2   16  nora            
3   35  james
4   21  ben

清单 2(生物测试):

id  test passed year   
1   100   yes   1
5   80    yes   n/a      
4   55    no    2

我正在尝试将每个 id 的测试值添加到 list1(不是每个 id 都有一个测试值)。

这是代码的一部分:

for (i in 1:length(list1)) { 
list1$test1value <- list2$test[match(list1$id[i], list2$id[i]),
nomatch = NA_integer_, incomparables = NULL)] }

而是通过 id 查找测试值,它只复制了 list2 中的第一个测试值并将其复制到 200 个单元格,其他 3000 个为 N/A。

怎么了?

【问题讨论】:

  • 改变了它。谢谢。
  • 这是昨天的related question。我的答案使用match 填充缺失值的行。使用merge 可以更轻松地解决您的问题。类似merge(df1, df2, by="id", all=TRUE)
  • 合并不适合我的目的,我不想创建一个不同的文件并将两者合并。我只想从每个 list2,list3.. 复制一个值到 list1具有相同的 ID。
  • 无论如何都会制作副本,merge 方法很容易应用。您可以重新分配给原始 data.frame:例如df1 &lt;- merge(df1, df2, by="id", all=TRUE)
  • 如果 list2 有 4000 个 id,而 list 1 有 5000 个 id,它将删除剩下的 1000 个。如果 list1 存在并且不存在,我需要向 list1 添加一个测试值。据我了解,match 与 excel 中的 vlookup 最相似。你知道我的匹配码有什么问题吗?

标签: r match vlookup


【解决方案1】:

首先,您的示例中有拼写错误。其次,“list1$test1value”的分配应该添加一个“[i]”,以免在每一轮中保存。也不应该将“[i]”添加到 list2$id,因为您要搜索整个向量以进行查找。

for (i in 1:length(list1)) { 
  list1$test1value[i] <- list2$test[match(list1$id[i], list2$id,
                             nomatch = NA_integer_, incomparables = NULL)] }

代码有效,但这里没有任何循环的原因。您对 R 的运作方式缺乏了解。下面的代码做同样的事情要快得多。

list1$test1value <- list2$test[match(list1$id, list2$id)]

R 的构建使您不必握住它的手并指示它如何遍历向量的每个元素。 match 将自动逐个遍历每个成员,并为您在另一个向量中查找它。它还将在数据集中有序地分配结果。

我将把它作为一个副本关闭,因为正如其他人所建议的那样,merge 非常适合这个。

merge(list1, list2[c("id", "test")], all.x=TRUE)
#  id age  name test
#1  1  40 danny  100
#2  2  16  nora   NA
#3  3  35 james   NA
#4  4  21   ben   55

【讨论】:

    猜你喜欢
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-20
    • 2015-10-17
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    相关资源
    最近更新 更多