Извлечь подмножество строк данных в зависимости от условий из других столбцов - PullRequest
0 голосов
/ 11 мая 2018

У меня есть 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

Я пытаюсь проанализировать подмножество данных.Подмножество, которое я хотел бы взять, - это данные, в которых ticker и strike совпадают.Но я также хочу получить эти данные, только если и put, и call существуют под type.С данными, приведенными выше, например, я хотел бы вернуть следующий результат:

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="_")

Затем использовать этот вектор только для извлечения значений там, где есть несколько идентификаторов.

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.

. Кроме того, формулировка названия может быть намного лучше, я прошу прощения

РЕДАКТИРОВАТЬ ::: проверив этот пост Поиск ВСЕХ дублирующих строк, включая «элементы с меньшими индексами»

Я также мог бы использовать это решение:

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

Ответы [ 3 ]

0 голосов
/ 11 мая 2018

Вы можете попробовать что-то вроде:

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". Я думал об использовании ключей, но не смог включить аспект "call" / "put".

0 голосов
/ 11 мая 2018

Я не являюсь пользователем пакета 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
0 голосов
/ 11 мая 2018

Редактирование ваших данных, чтобы дать случай, когда put и call не существует (я изменил самый последний "вызов" на "положить"):

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, вы можете использовать встроенный счетчик .N вместе с by переменными для подсчета групп и подмножеств с этим.Если при подсчете Type вы можете надежно определить, что есть и put, и call, это может сработать:

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

Часть, заключенная в первый набор [], выполняет подсчет, изатем [n > 1 & types == 2] выполняет поднабор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...