【问题标题】:Making rbind loop faster [duplicate]使rbind循环更快[重复]
【发布时间】:2018-05-29 16:05:54
【问题描述】:

我有一个两列数据框,其中左列中的值和右列中该值的频率。我想将这些数据反映在一个只有一列的新数据框中。

我已经让它与下面的 2 个 for 循环一起工作,但我的数据(100k+ 行和许多数据帧)非常慢。我尝试过使用 apply 功能,但无法解决。

library(tidyverse)

twocol <- tribble(
  ~value, ~count,
  0.23076923, 5,
  0.69076923, 3,
  1.15230769, 4,
  1.61384615, 4,
  2.15230769, 3
) %>% as.data.frame()

make_onecol <- function(df) {
  dfnew <- data.frame(value=NA)
  df %>% filter(count!=0) -> df
  for (i in 1:nrow(df)) {
    n <- df[i, 2]
    for (j in 1:n) {
      dfnew <- rbind(dfnew, df[i, 1])
    }
  }
  return(dfnew)
}

onecol <- make_onecol(twocol)

【问题讨论】:

  • 我不会说tidyverse,但你的目标是重复每个valuecount 次吗?然后你可以简单地做rep(twocol$value, twocol$count)

标签: r for-loop tidyverse rbind


【解决方案1】:

repdata.table 的包装器:

library(data.table)
setDT(twocol)[, .(value = rep(value, count))]
#     value
# 0.2307692
# 0.2307692
# 0.2307692
# 0.2307692
# 0.2307692
# 0.6907692
# 0.6907692
# 0.6907692
# 1.1523077
# 1.1523077
# 1.1523077
# 1.1523077
# ...

【讨论】:

  • 在生成 150000 行时,您的早期解决方案 data.frame(value = with(two_col, rep(value, count))) 的性能优于 data.table。我还没有检查更多的行数。
【解决方案2】:

您可以为此使用rep-函数。使用:

onecol <- data.frame(value = c(NA, rep(twocol$value, twocol$count)))

给予:

> onecol
       value
1         NA
2  0.2307692
3  0.2307692
4  0.2307692
5  0.2307692
6  0.2307692
7  0.6907692
8  0.6907692
9  0.6907692
10 1.1523077
11 1.1523077
12 1.1523077
13 1.1523077
14 1.6138462
15 1.6138462
16 1.6138462
17 1.6138462
18 2.1523077
19 2.1523077
20 2.1523077

【讨论】:

  • 非常感谢!伙计,我白费了很多麻烦! :)
猜你喜欢
  • 2017-08-23
  • 2021-02-13
  • 2022-01-23
  • 1970-01-01
  • 2018-10-03
  • 2016-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多