【问题标题】:Splitting a data.frame By Column Patterns and Binding Rows R按列模式和绑定行拆分data.frame R
【发布时间】:2019-09-10 18:53:36
【问题描述】:

我有一个 800x28000 的 data.frame。我想根据模式溢出列并绑定行。但是,我需要在此过程中创建一个名为“ticker”的新列。

这是数据框。

df1  = structure(list(AAPL.Price = c(20, 21), AAPL.Volume = c(100, 105
), MSFT.Price = c(30, 31), MSFT.Volume = c(150, 160)), class = "data.frame", row.names = c(NA, 
-2L))

print(df1)

  AAPL.Price AAPL.Volume MSFT.Price MSFT.Volume
1         20         100         30         150
2         21         105         31         160

我希望最终的数据框看起来像:

  Price Volume Ticker
1    20    100   AAPL
2    21    105   AAPL
3    30    150   MSFT
4    31    160   MSFT

我已经建立了一个不太好的解决方法。我正在寻找的答案与 Akrun 在此处提供的答案略有不同。 Split Data Every N Columns and rbind Using R 唯一的区别是,我需要在绑定行时创建一个额外的列“Ticker”。

这是我目前的工作。

library(foreach)

library(tidyverse)

ticker = c("AAPL", "MSFT")

rbind.table = function(ticker){
  header = paste0("^", ticker)
  df2 = df1[str_detect(names(df1), header)]%>%mutate(ticker = ticker)
  names(df2) = c("Price", "Volume", "Ticker")
  return(df2)
}


df2 = foreach(r = ticker, .packages = c("tidyverse", "stringr"), .combine = "bind_rows") %dopar% {rbind.table(r)}

print(df2)

  Price Volume Ticker
1    20    100   AAPL
2    21    105   AAPL
3    30    150   MSFT
4    31    160   MSFT

这是真实 data.frame 的屏幕截图。

【问题讨论】:

  • 我有 28k 列,需要 11 秒。我认为使用 data.table 可能会有更快的“最佳实践方式”。

标签: r dplyr data.table tidyverse


【解决方案1】:

dplyrtidyr 的一种可能性可能是:

df1 %>%
 rowid_to_column() %>%
 gather(var, val, -rowid) %>%
 separate(var, c("Ticker", "unit")) %>%
 spread(unit, val) %>%
 select(-rowid)

  Ticker Price Volume
1   AAPL    20    100
2   AAPL    21    105
3   MSFT    30    150
4   MSFT    31    160

【讨论】:

  • 嗨@tmnfk,在我的实际数据集中,每个股票代码都有25个变量。所以像(价格,成交量,隐含成交量,斜率......)。我更倾向于 data.table 模式识别。
  • 如果它具有示例中给出的结构(即.Price.Volume),那么它也应该与其他变量一起使用。如果您的实际数据不同,请发布适当的示例,否则将很难帮助您:)
  • 感谢@tmfmnk,我添加了实际 data.frame 的屏幕截图。我试过你的代码,但我似乎无法让它工作。我想我必须在 separate() 函数中指定一个不同的参数
  • 在您的实际数据的情况下,分隔代码和单位的分隔符是什么?对于示例数据,它是.
  • 我花了一点时间才弄清楚这一点,但我得到了它的工作!谢谢tmfmnk!非常感谢。但是,我将仅因为它在 data.table 中而排除上述答案。再次感谢:)
【解决方案2】:

列名模式需要更新以匹配您刚刚添加的屏幕截图,但可能仍然可以调整:

library(data.table)
df1 <- structure(
  list(
    AAPL.Price = c(20, 21),
    AAPL.Volume = c(100, 105), 
    MSFT.Price = c(30, 31), 
    MSFT.Volume = c(150, 160)
  ), class = "data.frame", row.names = c(NA,-2L)
)
dt1 <- as.data.table(df1)
tickers <- unique(sub(pattern = "\\..*$", replacement = "", x = colnames(dt1)))
vars <- unique(sub(pattern = ".*\\.(.*)$", replacement = "\\1", x = colnames(dt1)))

dt1_melted <- melt(dt1, measure = patterns(paste0(".", vars)), value.name = vars)[, Ticker := tickers[variable]][]
> dt1_melted
   variable Price Volume Ticker
1:        1    20    100   AAPL
2:        1    21    105   AAPL
3:        2    30    150   MSFT
4:        2    31    160   MSFT

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    相关资源
    最近更新 更多