当前位置: 首页 > 知识库问答 >
问题:

删除某列中某个值序列后的行

梁季
2023-03-14
a <- c("A","A","A","B","B","B","C","C","C","C","D","D","D","D","D")
b <- c("x","y","z","x","x","z","y","z","z","z","y","z","z","z","x")
df = data.frame(a,b)


    a   b
1   A   x
2   A   y
3   A   z
4   B   x
5   B   x
6   B   z
7   C   y
8   C   z
9   C   z
10  C   z
11  D   y
12  D   z
13  D   z
14  D   z
15  D   x

对于每个组A、B、C、D,每次组合y、z出现在组末尾时,我都想删除b列中的值z。

如果我们有 a==“C”的情况,其中 b 值是 y,z,z,z,z,我想删除所有 z。但是,在 a==“D” 中,由于 x 是最后一个值,因此无需更改任何内容。

结果如下所示:

    a   b
1   A   x
2   A   y
4   B   x
5   B   x
6   B   z
7   C   y
11  D   y
12  D   z
13  D   z
14  D   z
15  D   x

通过在< code>dplyr中进行分组,我可以确定每个值在A中最后出现的位置,因此< code>a=="A"中描述的基本情况不成问题。对于< code>a=="C"的情况,我很难找到解决方案,在这种情况下,y出现一次,z出现20次。

共有3个答案

林星阑
2023-03-14

这是一个基本的解决方案:

do.call("rbind", by(df, df$a, FUN = function(x) {
    if(x$b[length(x$b)] == "z") {
        y <- which(x$b == "y")
        if(!length(y)) {
            return(x)
        }
        z <- which(x$b == "z")
        if(!length(z)) {
            return(x)
        }
        # check if y isn't immediately before z
        if(max(y) - min(z) > 1) {
            return(x)
        } else {
            return(x[-z,])
        }
    } else {
        return(x)
    }
}))

结果是:

     a b
A.1  A x
A.2  A y
B.4  B x
B.5  B x
B.6  B z
C    C y
D.11 D y
D.12 D z
D.13 D z
D.14 D z
D.15 D x
郑正阳
2023-03-14

这里有一个可能的< code>data.table解决方案。基本上,我正在创建一个同时满足3个条件的逻辑索引:作为一个< code>z,第一个< code>z在< code>y之后,最后一个值是< code>z,然后我就对它求值。

library(data.table)
setDT(df)[, indx := b == "z" & 
            max(which(b == "z")) == .N &
            ifelse(min(which(b == "z")) == 1L, 
                   TRUE, 
                   b[min(which(b == "z")) - 1L] == "y"),
            by = a][!(indx)]
#     a b  indx
#  1: A x FALSE
#  2: A y FALSE
#  3: B x FALSE
#  4: B x FALSE
#  5: B z FALSE
#  6: C y FALSE
#  7: D y FALSE
#  8: D z FALSE
#  9: D z FALSE
# 10: D z FALSE
# 11: D x FALSE
伍心水
2023-03-14

您可以使用bycumminbaseR:

df[unlist(by(df$b, interaction(df$a), FUN = function(x) {
  tmp <- rev(cummin(rev(x == "z")))
  if (tail(x[!tmp], 1) == "y") !tmp else rep(TRUE, length(x))
})), ]

结果:

   a b
1  A x
2  A y
4  B x
5  B x
6  B z
7  C y
11 D y
12 D z
13 D z
14 D z
15 D x
 类似资料:
  • 我有这个,并且只需要列不是的记录: ...即。类似于的内容,以获取结果数据规则: 我该怎么做?

  • 我在MySQL中的查询有问题。我的表有4列,看起来如下所示: 和是来自不同表的外键。 我只想删除一行: 它出现了两次,所以我只想删除它。 我尝试了以下查询: 但它将删除这两个(因为它们是重复的)。有什么关于解决这个问题的提示吗?

  • 我有下表和Postgres: 作为select查询的一部分,我希望能够基于最高的Col2值(每个Col1值永远不会有多个最高值)在Col1中删除重复项,并保留相应的Col2、Col3值。 期望输出:

  • 问题内容: 我正在尝试从具有相同的第一项和第三项但仅保留第一项的列表中删除列表。示例列表和输出: 由于原始列表包含数百万个列表,因此我编写的代码需要很长时间才能执行。 如何改善代码?提前致谢。 问题答案: 改进的版本: 更改为: 使用的,这使得查找更快。 转成元组,因为没有必要存储唯一的第一和第三元素列表。 减少的函数查找也可以加快代码的速度。

  • 这是我的数据样本 我编写了以下代码,它删除了所有分类列(例如)。但是,一些非类别列具有值。如何将它们从我的数据集中排除。 当我运行程序时,我得到错误来说太大的值,我认为这是由于值造成的。 问题1-我如何完全删除这些行问题2-这些列的类型是什么,大部分是NO。但两者之间有短信吗?我想我将执行,但这并没有给出结果

  • 问题内容: 我使用GSON进行序列化时,没有找到一种方法,无法根据Gson根据字段值提供的ExclusionStrategy类从序列化中排除某些字段,因为它仅支持基于顶级类或字段属性的排除。字段属性不包括该字段的值。所以我该怎么做? 问题答案: 实现此目的的方法是为相关类创建自定义序列化程序。在允许Gson以默认方式创建JSON对象之后,请根据其值删除要排除的属性。 并在用于此类的应用程序中用于序