【问题标题】:Comparing vectors比较向量
【发布时间】:2011-05-19 05:28:27
【问题描述】:

我是 R 新手,正在努力寻找更好的解决方案来有效地完成这个相当简单的任务。

我有一个 data.frame M100,000 行(以及许多列,其中 2 列与此问题相关,我将其称为 M1M2)。我还有另一个data.frame,其中包含大约10,000 个元素的列V1 对这项任务至关重要。我的任务是:

对于V1中的每一个元素,找出它在M2中出现的位置,并拉出对应的M1。我可以使用 for-loop 来做到这一点,而且速度非常慢!我习惯了 Matlab 和 Perl,这在 R 中是永远的!肯定有更好的办法。在完成这项任务时,我将不胜感激任何有价值的建议......

for (x in c(1:length(V$V1)) {  
    start[x] = M$M1[M$M2 == V$V1[x]]  
}  

只有 1 个元素会匹配,所以我可以使用逻辑语句直接获取起始向量中的元素。我怎样才能矢量化这个?

谢谢!

【问题讨论】:

    标签: optimization r vector


    【解决方案1】:

    这是使用@aix 相同示例的另一个解决方案。

    M[match(V$V1, M$M2),]

    要对性能进行基准测试,我们可以使用 R 包rbenchmark

    library(rbenchmark)
    f_ramnath = function() M[match(V$V1, M$M2),]
    f_aix = function() merge(V, M, by.x='V1', by.y='M2', sort=F)
    f_chase = function() M[M$M2 %in% V$V1,] # modified to return full data frame
    
    benchmark(f_ramnath(), f_aix(), f_chase(), replications = 10000)
         test replications elapsed relative
    2     f_aix()        10000  12.907 7.068456
    3   f_chase()        10000   2.010 1.100767
    1 f_ramnath()        10000   1.826 1.000000
    

    【讨论】:

    • %in% 应该以与match 类似的方式执行,因为它只是match 的包装器
    • @chase。我尝试了您的解决方案,并期望%in% 以与match 相同的方式执行。但是当我运行benchmark 时,我惊讶地发现`%in% 慢了10%。想知道是什么原因造成的。
    • @Ramnath - 感谢更新测试。这可能是nomatch 参数之间的区别吗?默认为nomatch = NA_integer_%in% 使用nomatch = 0
    • @Chase。我想这可能是解释。我将使用match的解决方案修改为使用nomatch = 0,性能类似于%in%。我还对您生成的数据集进行了基准测试,发现match 解决方案比%in% 慢10%。所以这里可能还会发生其他事情。
    • 模拟 OP 数据时序不同:N <- 100000; n <- 10000; M <- data.frame(M1=sample(seq_len(N)), M2=sample(seq_len(N))); V <- data.frame(V1=sample(seq_len(N),n))。追逐解决方案更快。
    【解决方案2】:

    另一种选择是使用%in% 运算符:

    > set.seed(1)
    > M <- data.frame(M1 = sample(1:20, 15, FALSE), M2 = sample(1:20, 15, FALSE))
    > V <- data.frame(V1 = sample(1:20, 10, FALSE))
    > M$M1[M$M2 %in% V$V1]
    [1]  6  8 11  9 19  1  3  5
    

    【讨论】:

      【解决方案3】:

      听起来你在寻找merge

      > M <- data.frame(M1=c(1,2,3,4,10,3,15), M2=c(15,6,7,8,-1,12,5))
      > V <- data.frame(V1=c(-1,12,5,7))
      > merge(V, M, by.x='V1', by.y='M2', sort=F)
        V1 M1
      1 -1 10
      2 12  3
      3  5 15
      4  7  3
      

      如果V$V1 可能包含M$M2 中不存在的值,您可能需要指定all.x=T。这将用 NA 填充缺失的值,而不是从结果中省略它们。

      【讨论】:

        猜你喜欢
        • 2012-10-04
        • 2013-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多