【问题标题】:How to filter large data-sets by two attributes and split into subsets? R / Grep如何通过两个属性过滤大型数据集并拆分为子集? R / grep
【发布时间】:2017-02-22 19:57:13
【问题描述】:

我发现自己处于 grep() 函数的极限,或者也许有有效的方法来做到这一点。

开始一个示例数据框:

Date <- c( "31-DEC-2014","31-DEC-2014","31-DEC-2014","30-DEC-2014",
           "30-DEC-2014","30-DEC-2014", "29-DEC-2014","29-DEC-2014","29-DEC-2014" )

ISIN <- c("LU0168343191", "TW0002418001", "GB00B3FFY088","LU0168343191",
          "TW0002418001", "GB00B3FFY088","LU0168343191", "TW0002418001", "GB00B3FFY088")


price <-c(seq(1:9))

df <- as.data.frame(cbind(Date, ISIN, price))

所需的结果是一个 list() 包含主数据文件的子集,如下所示(Result_I 中的 3 个单独标识符的 x3)

想法是数据应首先按 ISIN 过滤,然后然后按日期过滤。这两个步骤的过程应该保持我的数据完好无损。

Result_d <- c("31-DEC-2014", "30-DEC-2014","29-DEC-2014")
Result_I <- c("LU0168343191","LU0168343191","LU0168343191")
Result_P <- c(1,4,7)

Result_df <- cbind(Result_d, Result_I, Result_P)

请保持上述内容用于演示目的,真实数据集在 450 多个不同日期期间有 500 万行和 50 列,根据Result_d,所以我正在寻找适用的东西,而与 nrow 无关或 ncol

到目前为止我所拥有的:

我记录所有唯一的日期并存储:

Unique_Dates <- unique(df$Date)

标识符相同:

Unique_ID <- unique(df$ISIN)

现在是 grepping 问题:

如果我想要所有包含 Unique_Dates 的行,我会这样做:

pattern <- paste(Unique_dates, collapse = "|")

result <- as.matrix(df[grep(pattern, df$Date),])

这将基本上检索整个数据集。我想知道是否有人知道这样做的有效方法。

提前致谢。

【问题讨论】:

  • df %&gt;% dplyr::filter(grepl(pattern = "LU", ISIN)) 对于日期和范围,请使用 lubridate
  • 您似乎只想保留每个日期的第一行,所以:df[!duplicated(df$Date),] 也许?
  • 您的代码输出错误。它也仅限于“LU”,我在这里有大约 8000 个唯一 ID。我在同一日期也有多个相同 ID 的条目,因此应用唯一的日期过滤器很重要
  • Maximus,为了保持数据质量,重要的是它们首先按 ID 过滤 1,然后按日期过滤
  • Alex,试着更好地描述你的输出是如何计算的。

标签: r split subset


【解决方案1】:

使用dplyr

library(dplyr)

Date <- c( "31-Dec-2014","31-Dec-2014","31-Dec-2014","30-Dec-2014",
           "30-Dec-2014","30-Dec-2014", "29-Dec-2014","29-Dec-2014","29-Dec-2014" )

ISIN <- c("LU0168343191", "TW0002418001", "GB00B3FFY088","LU0168343191",
          "TW0002418001", "GB00B3FFY088","LU0168343191", "TW0002418001", "GB00B3FFY088")


price <-c(seq(1:9))

DF <- data.frame(Date, ISIN, price,stringsAsFactors=FALSE)
DF$Date=as.Date(DF$Date,"%d-%b-%Y")



#Examine data ranges and frequencies

#date range
range(DF$Date)

#date frequency count
table(DF$Date)

#ISIN frequency count
table(DF$ISIN)


#select ISINs for filtering, with user defined choice of filters

# numISIN = 2
# subISIN = head(names(sort(table(DF$ISIN))),numISIN)


subISIN = names(sort(table(DF$ISIN)))[2]


subDF=DF %>%
dplyr::group_by(ISIN) %>%
dplyr::arrange(ISIN,Date) %>%
dplyr::filter(ISIN %in% subISIN) %>%  
as.data.frame()

#> subDF
#        Date         ISIN price
#1 2014-12-29 LU0168343191     7
#2 2014-12-30 LU0168343191     4
#3 2014-12-31 LU0168343191     1

【讨论】:

    【解决方案2】:

    我们将“data.frame”转换为“data.table”(setDT(df)),按“日期”分组,根据grep 返回的索引指定“i”,并将 Data.table 子集( .SD) 基于 'i' 索引。

    library(data.table)
    setDT(df)[grep("LU", ISIN), .SD, by = Date]
    #           Date         ISIN price
    #1: 31-DEC-2014 LU0168343191     1
    #2: 30-DEC-2014 LU0168343191     4
    #3: 29-DEC-2014 LU0168343191     7
    

    【讨论】:

    • 应用于我的主要数据时出现此错误:[.data.table(setDT(PORTFO_Dat2), grep("LU0168343191", PORTFO_Dat2$ISIN.code), 中的错误:'by' 中的项目或 'keyby' 列表的长度 (5114748)。每个必须与 x 中的行或 i (120) 返回的行数相同。
    • @AlexBădoi 我没有使用PORTFO_Dat2$。应该是ISIN.code
    • 令人惊讶的是,它的效果如此之好,而且应用起来如此简单。我所要做的就是遍历我所有的 ID。谢谢
    • 你好,arkun,你能解释一下函数的 .SD 部分是做什么的吗?
    • @AlexBădoi 我更新了帖子。 .SD 表示 Data.table 的子集
    猜你喜欢
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 1970-01-01
    • 2022-10-01
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    相关资源
    最近更新 更多