【问题标题】:Pull subset of rows of dataframe based on conditions from other columns根据其他列的条件提取数据帧行的子集
【发布时间】:2018-10-21 23:35:04
【问题描述】:

我有一个dataframe,如下所示:

x <- data.table(Tickers=c("A","A","A","B","B","B","B","D","D","D","D"),
                Type=c("put","call","put","call","call","put","call","put","call","put","call"),
                Strike=c(35,37.5,37.5,10,11,11,12,40,40,42,42),
                Other=sample(20,11))

    Tickers Type Strike Other
 1:       A  put   35.0     6
 2:       A call   37.5     5
 3:       A  put   37.5    13
 4:       B call   10.0    15
 5:       B call   11.0    12
 6:       B  put   11.0     4
 7:       B call   12.0    20
 8:       D  put   40.0     7
 9:       D call   40.0    11
10:       D  put   42.0    10
11:       D call   42.0     1

我正在尝试分析数据的一个子集。我想采用的子集是tickerstrike 相同的数据。但是我也只想在type 下同时存在putcall 时获取这些数据。以上面的数据为例,我想返回以下结果:

x[c(2,3,5,6,8:11),]

   Tickers Type Strike Other
1:       A call   37.5     5
2:       A  put   37.5    13
3:       B call   11.0    12
4:       B  put   11.0     4
5:       D  put   40.0     7
6:       D call   40.0    11
7:       D  put   42.0    10
8:       D call   42.0     1

我不确定执行此操作的最佳方法是什么。我的想法是我应该创建另一个列向量,例如

x$id <- paste(x$Tickers,x$Strike,sep="_")

然后使用这个向量只提取有多个 id 的值。

x[x$id %in% x$id[duplicated(x$id)],]

   Tickers Type Strike Other     id
1:       A call   37.5     5 A_37.5
2:       A  put   37.5    13 A_37.5
3:       B call   11.0    12   B_11
4:       B  put   11.0     4   B_11
5:       D  put   40.0     7   D_40
6:       D call   40.0    11   D_40
7:       D  put   42.0    10   D_42
8:       D call   42.0     1   D_42

我不确定这样做的效率如何,因为我的实际数据包含更多行。 此外,此解决方案不会检查 type 的条件,即有一个 put 和一个 call

标题的措辞可能会好很多,我很抱歉

编辑::: 已查看此帖子Finding ALL duplicate rows, including "elements with smaller subscripts"

我也可以使用这个解决方案:

x$id <- paste(x$Tickers,x$Strike,sep="_")
x[duplicated(x$id) | duplicated(x$id,fromLast=T),]

【问题讨论】:

    标签: r dataframe datatable subset


    【解决方案1】:

    你可以试试这样的:

    x[, select := (.N >= 2 & all(c("put", "call") %in% unique(Type))), by = .(Tickers, Strike)][which(select)]
    
    #   Tickers Type Strike Other select
    #1:       A call   37.5    17   TRUE
    #2:       A  put   37.5    16   TRUE
    #3:       B call   11.0    11   TRUE
    #4:       B  put   11.0    20   TRUE
    #5:       D  put   40.0     1   TRUE
    #6:       D call   40.0    12   TRUE
    #7:       D  put   42.0     6   TRUE
    #8:       D call   42.0     2   TRUE
    

    另一个想法可能是合并:

    x[x, on = .(Tickers, Strike), select := (length(Type) >= 2 & all(c("put", "call") %in% Type)),by = .EACHI][which(select)]
    

    我不完全确定如何绕过分组操作,因为您想确保每个组都有“call”和“put”。我正在考虑使用键,但无法合并“调用”/“放置”方面。

    【讨论】:

    • 我喜欢这个 - all(c("put", "call") %in% unique(Type)) 部分比我的解决方案更强大。
    • 感谢@BrianStamper,部分灵感来自您的解决方案,所以谢谢!
    • which(select) 结构是我必须记住的!
    • 非常好的解决方案!我也非常感谢all(c("put", "call") %in% unique(Type)) 部分。如果我的 type 变量要包含其他选项组合,这将允许更复杂的子集。如果我想将另一列作为组的一部分,我也可以简单地添加它by = .(Tickers, Strike) 对吗?
    【解决方案2】:

    对您的数据进行编辑以给出putcall 都不存在的情况(我将最后一个“调用”更改为“放置”):

    x <- data.table(Tickers=c("A","A","A","B","B","B","B","D","D","D","D"),
                Type=c("put","call","put","call","call","put","call","put","call","put","put"),
                Strike=c(35,37.5,37.5,10,11,11,12,40,40,42,42),
                Other=sample(20,11))
    

    由于您使用的是data.table,因此您可以使用内置计数器.Nby 变量来计算组和子集。如果通过计算Type,您可以可靠地确定同时存在putcall,这可能会起作用:

    x[, `:=`(n = .N, types = uniqueN(Type)), by = c('Tickers', 'Strike')][n > 1 & types == 2]
    

    第一组[] 中的部分进行计数,然后[n &gt; 1 &amp; types == 2] 进行子集。

    【讨论】:

    • 我喜欢这个解决方案!我将创建更大、更符合我的完整数据大小的样本数据,并尽快比较结果!
    【解决方案3】:

    我不是包 data.table 的用户,所以此代码仅是基本 R。

    agg <- aggregate(Type ~ Tickers + Strike, data = x, length)
    result <- merge(x, subset(agg, Type > 1)[1:2], by = c("Tickers", "Strike"))[, c(1, 3, 2, 4)]
    result
    #   Tickers Type Strike Other
    #1:       A call   37.5    17
    #2:       A  put   37.5     7
    #3:       B call   11.0    14
    #4:       B  put   11.0    20
    #5:       D  put   40.0    15
    #6:       D call   40.0     2
    #7:       D  put   42.0     8
    #8:       D call   42.0     1
    
    
    rm(agg)    # final clean up
    

    【讨论】:

      猜你喜欢
      • 2014-08-03
      • 2020-02-10
      • 2017-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多