【问题标题】:Assigning group ID with ddply使用 ddply 分配组 ID
【发布时间】:2023-03-09 06:30:01
【问题描述】:

来自 R 新手的非常基本的性能问题。我想通过字段的唯一组合为数据框中的每一行分配一个组 ID。这是我目前的方法:

> # An example data frame
> df <- data.frame(name=c("Anne", "Bob", "Chris", "Dan", "Erin"), 
                   st.num=c("101", "102", "105", "102", "150"), 
                   st.name=c("Main", "Elm", "Park", "Elm", "Main"))
> df
   name st.num st.name
1  Anne    101    Main
2   Bob    102     Elm
3 Chris    105    Park
4   Dan    102     Elm
5  Erin    150    Main
> 
> # A function to generate a random string
> getString <- function(size=10) return(paste(sample(c(0:9, LETTERS, letters), size, replace=TRUE), collapse=''))
>
> # Assign a random string for each unique street number + street name combination
> df <- ddply(df, 
              c("st.num", "st.name"), 
              function(x) transform(x, household=getString()))
> df
   name st.num st.name  household
1  Anne    101    Main 1EZWm4BQel
2   Bob    102     Elm xNaeuo50NS
3   Dan    102     Elm xNaeuo50NS
4 Chris    105    Park Ju1NZfWlva
5  Erin    150    Main G2gKAMZ1cU

虽然这适用于行数相对较少或组数较少的数据帧,但我遇到了具有许多唯一组的较大数据集(> 100,000 行)的性能问题。

有什么建议可以提高这个任务的速度吗?可能与 plyr 的实验性 idata.frame() 一起使用?还是我做错了?

提前感谢您的帮助。

【问题讨论】:

    标签: r plyr


    【解决方案1】:

    尝试使用 id 函数(也在 plyr 中):

    df$id <- id(df[c("st.num", "st.name")], drop = TRUE)
    

    更新:

    自 dplyr 版本 0.5.0 起,id 函数被视为已弃用。 函数group_indices 提供相同的功能。

    【讨论】:

    • 显然我需要回去更仔细地阅读 plyr 文档——这正是我想要的。我在我的测试数据集上评估了这个解决方案和 JoFrhwld:一个基于 3 个分组变量的具有 164,961 个观察值和 91,876 个唯一组的数据框。我使用这些方法中的每一种分配一个组 ID 变量 100 次。 id() 的平均经过时间为 0.958 (sd .0310)。粘贴分组字段的平均经过时间为 1.94 (sd .0946)。感谢两位!
    【解决方案2】:

    ID必须是随机的10个字符的字符串吗?如果没有,为什么不将数据框的列粘贴在一起。如果 ID 的字符长度必须相同,请将因子转换为数字,然后将它们粘贴在一起:

    df$ID <- paste(as.numeric(df$st.num), as.numeric(df$st.name), sep = "")
    

    然后,如果你真的需要 10 个字符 ID,我会只生成 n 个 ID,并用它们重命名 ID 的级别

    df$ID <- as.factor(df$ID)
    n <- nlevels(df$ID)
    
    getID <- function(n, size=10){
      out <- {}
      for(i in 1:n){
        out <- c(paste(sample(c(0:9, LETTERS, letters), size, replace=TRUE), collapse=''))
      }
      return(out)
    }
    
    newLevels <- getID(n = n)
    
    levels(df$ID) <- newLevels
    

    另外,顺便说一句,您不需要像 transform() 那样将 function(x) 与 ddply 一起使用。这段代码也一样:

    ddply(df, c("st.num", "st.name"), transform, household=getString())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 2014-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多