在特定条件下从数据框中提取行

Posted

技术标签:

【中文标题】在特定条件下从数据框中提取行【英文标题】:Extract rows from a data frame under certain conditions 【发布时间】:2019-06-11 13:30:33 【问题描述】:

我必须根据特定条件过滤我的数据框。 如果解决方案考虑使用 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,还要收集具有相同 的所有 Rows sentID 和前一个的合作伙伴价值

预期的结果是这样的:

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

【问题讨论】:

【参考方案1】:

我们可以使用%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))

【讨论】:

有必要将 groupBy 也扩展到“partner”值。它以这种方式工作。谢谢 @Silvia 我也加了partner【参考方案2】:

我们可以首先找出我们感兴趣的label 值所在的行索引,然后使用这些索引从整个数据帧中对sentIdpartner 值进行子集化。

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])

【讨论】:

【参考方案3】:

这个问题可以很容易地用 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)

Demo

注意:上面的演示实际上使用了 MariaDB,因为 SQLite 没有使用演示工具。但它仍然表明查询逻辑是正确的。

【讨论】:

【参考方案4】:

使用sqldf: 它将标签为 3 的 sentIDpartner 提取为两个内部查询,并从中获取结果。

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

【讨论】:

注意:实际的列名中包含点,因此您必须使用底层数据库引擎的特定语法对它们进行转义。 @TimBiegeleisen:感谢您的纠正。从列名中删除第一个 . 以使其更容易。

以上是关于在特定条件下从数据框中提取行的主要内容,如果未能解决你的问题,请参考以下文章

根据列值从熊猫数据框中提取行

python进行数据库查询中怎么把结果提取出来,跪谢

从熊猫数据框中提取特定信息

如何根据在熊猫数据框中的其他列上应用条件来提取列值

Meteor / MongoDB - 如何证明数组中的任何项目是不是等于特定值,而不是在“真”的情况下从另一个数组中提取项目?

从 pyspark 数据框中的列中提取特定字符串