【问题标题】:R Check a row of strings, if equal, assign equal ID, less time consumingR 检查一行字符串,如果相等,分配相等的ID,耗时少
【发布时间】:2017-03-25 16:24:20
【问题描述】:

我对 R 相当陌生,想知道这里是否有人对我的问题有更好的解决方案,因为我的问题太耗时了。我知道 R 不是很“for-loop-friendly”,所以我确信有更好的方法来解决这个问题。

我有一个数据框,其中 x 是文本字符串,y 是数字 id:

x = c("a", "b", "c", "b", "a")
y = c(1,2,3,4,5)
df <- data.frame(x, y)

我希望 a 找到 x 列中的所有匹配项,并为它们分配与 y 中的第一个相同的数值。我用以下方法解决了这个问题:

library(foreach)
library(iterators)

for(i in 1:NROW(df)) {
  for(j in i:NROW(df)) {
    if(df$x[j] == df$x[i]){
      df$y[j] <- df$y[i]
    }
    j = j + 1
  }
  i = i + 1
}

问题是,我有一个相当大的数据集,这使得这个过程需要很多时间!希望这里的任何人都知道一个更省时的选择!

【问题讨论】:

    标签: r performance time dataframe match


    【解决方案1】:

    如果您的数据集确实很大,那么 data.table 可能是最快的解决方案(请参阅基准here)。

    library(data.table)
    setDT(df)
    
    df[, y := first(y), by = x]
    

    【讨论】:

    • 这使用相对较大的数据集立即解决了问题。但是,这种方法的结果是 y 中的值不是连续的。无论如何,它解决了我的问题!
    • 您可以将key 更改为keyby,这将对x 进行排序(如果这是您的意思)。您还可以使用setorder(df, x) 快速就地排序。
    • 哎呀没关系,我输入的值顺序错误...哈哈
    【解决方案2】:

    R 喜欢矢量化代码,因此如果在循环中完成算术运算和赋值之类的事情可能会很慢。例如,考虑以两种不同的方式将向量 1、2、... 1,000,000 分配给变量 x

    x <- 1:1e6
    

    和

    x <- numeric(x, 1e6) # initialise a numeric vector of length 1 million
    for (i in 1:1e6) x[i] <- i
    

    如果您尝试一下,您会发现第二种方法需要更长的时间。

    遇到您的问题,您想按df$x 中的值对数据进行分组,并将y 的值替换为其第一个元素

    df.by <- by(df$x, function(d) transform(d, y = y[1]), data = df)
    

    会将df(基于df$x 的子集)的每个子集的第二列设置为其第一个元素。结果是

    #df$x: a
    #  x y
    #1 a 1
    #5 a 1
    #------------------------------------------------------------
    #df$x: b
    #  x y
    #2 b 2
    #4 b 2
    #------------------------------------------------------------
    #df$x: c
    #  x y
    #3 c 3
    

    要将这些组合回数据框,请使用df.new &lt;- do.call(rbind, df.by)。此操作的一个(可能是不需要的)副作用是它将更改行的顺序。

    如果您是 R 新手,请查看 dplyr 包,它具有流畅的学习曲线和易于编写和阅读的语法。您想要做的事情只需几行就可以完成。

    library(dplyr)
    df %>% group_by(x) %>% mutate(y = y[1])
    

    会做的!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      • 2010-10-10
      • 2015-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多