Извлечение строк из фрейма данных при определенных условиях - PullRequest
0 голосов
/ 17 января 2019

Я должен отфильтровать свой фрейм данных в зависимости от конкретного условия. Лучше, если решение предусматривает использование dplyr.

У меня есть структура данных, как эта

  sentId.   B.   label.   partner. code
    1.      2.     3.       4.      123
    1.      2.     2.       4.      124
    4.      2.     3.       8.      125
    7.      3.     2.       7.      126

Если столбец label содержит определенное значение (например, 3.), соберите не только эту Row , но и все строки, имеющие одинаковый sentID и значение партнера предыдущего.

Ожидаемые результаты таковы:

  sentId.   B.   label.   partner. code
    1.      2.     3.       4.      123
    1.      2.     2.       4.      124
    4.      2.     3.       8.      125

Ответы [ 4 ]

0 голосов
/ 17 января 2019

Использование sqldf: Он извлекает sentID и partner с меткой 3 как два внутренних запроса и извлекает результат из него.

names(df) <- gsub("\\.", "", names(df)) # to remove . from column name
sqldf("select * from df where (sentID IN (select sentID from df where label IS 3) OR 
      partner IN (select partner from df where label IS 3))")

Выход:

  sentId B label partner code
1      1 2     3       4  123
2      1 2     2       4  124
3      4 2     3       8  125
0 голосов
/ 17 января 2019

Сначала мы можем найти индексы строк, в которых у нас есть интересующее значение label, а затем использовать эти индексы для подстановки значений sentId и partner из всего фрейма данных.

label_value <- 3
inds <- df$label == label_value
df[with(df, sentId %in% sentId[inds] & partner %in% partner[inds]), ]

#  sentId B label partner code
#1      1 2     3       4  123
#2      1 2     2       4  124
#3      4 2     3       8  125

Та же логика в dplyr будет

library(dplyr)

df %>%
  filter(sentId %in% sentId[label == label_value] & 
         partner %in% partner[label == label_value])
0 голосов
/ 17 января 2019

Эта проблема может быть легко сформулирована с использованием SQL, поэтому одним из вариантов будет использование библиотеки sqldf:

library(sqldf)

# your data frame df
sql <- "SELECT t1.\"sentId.\", t1.\"B.\", t1.\"label.\", t1.\"partner.\", t1.code
        FROM yourTable t1
        WHERE t1.\"label.\" = '3.' OR
            EXISTS (SELECT 1 FROM yourTable t2
                    WHERE t1.\"sentId.\" = t2.\"sentId.\" AND
                          t1.\"partner.\" = t2.\"partner.\" AND
                          t2.\"label.\" = '3.')"

result <- sqldf(sql)

enter image description here

Демонстрация

Примечание. Приведенная выше демка фактически использует MariaDB, поскольку SQLite не работал с демо-инструментом.Но это все еще показывает, что логика запроса верна.

0 голосов
/ 17 января 2019

Мы можем использовать строки от %in% до filter после группировки по 'sentId` и' partner. '

library(dplyr)
df1 %>%
  group_by(sentId., partner.) %>%
  filter(3 %in% label.)
# A tibble: 3 x 5
# Groups:   sentId. [2]
#  sentId.    B. label. partner.  code
#    <dbl> <dbl>  <dbl>    <dbl> <int>
#1       1     2      3        4   123
#2       1     2      2        4   124
#3       4     2      3        8   125

Или компактно с data.table

library(data.table)
setDT(df1)[, .SD[3 %in% label.], .(sentId., partner.)]

Или с base R

df1[with(df1, ave(label.==3, sentId., partner., FUN = any)),]

данные

df1 <- structure(list(sentId. = c(1, 1, 4, 7), B. = c(2, 2, 2, 3), label. = c(3, 
 2, 3, 2), partner. = c(4, 4, 8, 7), code = 123:126),
 class = "data.frame", row.names = c(NA, 
 -4L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...