【问题标题】:R: Combining data.frames in a more elegant wayR:以更优雅的方式组合 data.frames
【发布时间】:2017-08-14 13:16:07
【问题描述】:

我正在构建一个基于随机条目/行的数据框。这是创建随机条目的函数:

createRandomEntry <- function() {
    names <- c('Dilbert', 'Wally', 'Alice', 'Ashok', 'Topper')
    ages <- 30:45
    return(
        data.frame(
            Name = sample(names, 1),
            Age = sample(ages, 1),
            stringsAsFactors = FALSE
        )
    )
}

现在我使用这个函数将它们组合成一个大的data.frame

createRandomEntries <- function(n) {
    df <- createRandomEntry()
    for (i in 2:n) {
        df <- rbind(df, createRandomEntry())
    }
    return(df)
}

从技术上讲,它运行良好,但由于多种原因有点笨拙:

  • 我必须在两个地方调用createRandomEntry() 函数
  • 我必须使用循环
    • 循环必须从索引 2 开始,因为我已经获得了第一个条目
  • 也许打电话给rbind,这通常可能效率低下,我不知道...

在早期版本中,createRandomEntry() 返回 list 而不是 data.frame。然后我使用replicate() 创建一个矩阵,首先必须对其进行转置(通过调用t())才能从中创建一个data.frame。并且 data.frame 不可排序(错误:“'orderVector1' 中的未实现类型 'list'”)。在每一行上调用 unlist() 或从 createRandomEntry() 返回一个向量将解决排序问题,但我只会在每一列中获取字符串。

一定有更好的方法。但是怎么做呢?

编辑:拥有一个创建单个条目的函数很重要,因为一个条目的某些值可能相互关联,例如这个增强的函数显示:

createRandomEntry <- function() {
    names <- c('Dilbert', 'Wally', 'Alice', 'Ashok', 'Topper')
    ages <- 30:45
    startedIn <- sample(1995:2005, 1)
    lostMotivation <- startedIn + sample(1:3, 1)
    return(
        data.frame(
            Name = sample(names, 1),
            Age = sample(ages, 1),
            StartYear = startedIn,
            LostMotivation = lostMotivation,
            stringsAsFactors = FALSE
        )
    )
}
createRandomEntries(3)

产生:

     Name Age StartYear LostMotivation
1   Ashok  42      1998           2000
2 Dilbert  43      1997           1999
3 Dilbert  30      1996           1999

【问题讨论】:

  • do.call('rbind.data.frame', lapply(1:100, function(i) createRandomEntry()))
  • 想想dplyr::rbind_list 并将每个示例数据框保存到一个列表中,而不是一次又一次地覆盖您的data.frame
  • @bouncyball,你打败了我,可能do.call(rbind, lapply(1:100, createRandomEntry)) 也可以。

标签: r


【解决方案1】:

只需将n 从第二个函数移动到第一个函数?

createRandomEntries <- function(n) {
    names <- c('Dilbert', 'Wally', 'Alice', 'Ashok', 'Topper')
    ages <- 30:45
    return(
        data.frame(
            Name = sample(names, n, TRUE),
            Age = sample(ages, n, TRUE),
            stringsAsFactors = FALSE
        )
    )
}

【讨论】:

  • 对于这个人为的例子来说确实是一种选择,但是如果一个条目的两个字段会以某种方式相互关联怎么办?假设我有一个随机日期字段“开始”和另一个日期字段“结束”,并在一定范围内添加了一定天数。所以必须有一个生成单个条目的函数。
  • 如果您的问题与日期有关,请考虑生成start_date,然后使用merge(这是一个连接链接函数)添加end_date。否则@bouncyball 解决方案应该没问题!
  • 嗯,可能我用太多的 C 思维来处理 R,在这种情况下,操作不能那么容易地应用于整个数据集......
【解决方案2】:

根据 Bruno Zamengo 的回答,我现在重写了函数:

createRandomEntries <- function(n) {
    names <- c('Dilbert', 'Wally', 'Alice', 'Ashok', 'Topper')
    ages <- 30:45
    df <- data.frame(
        Name = sample(names, n, replace = TRUE),
        Age = sample(ages, n, replace = TRUE),
        StartYear = sample(1995:2005, n, replace = TRUE),
        stringsAsFactors = FALSE
    )
    df$LostMotivation <- df$StartYear + sample(1:3, n, replace = TRUE)
    return(df)
}

但是,我没有按照建议使用merge

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多