【问题标题】:How do I delete the last row of a group in r based on conditions in a different row in r如何根据 r 中不同行的条件删除 r 中组的最后一行
【发布时间】:2017-11-17 22:24:27
【问题描述】:

我有一个这样的数据框(比如说,NT 和 MCS 是某个物种的文本占位符)

A <- c("NT", "MCS","MCS","NT", "MCS", "MCS", "NT", "MCS", "MCS", "MCS", 
       "NT", "MCS", "MCS","NT", "MCS","NT","NT","MCS", "MCS","NT")
B <- c("1", "3", "3","3","3", "3","3","4","4","4","4","3", 
       "3","3","2","2","1","3","3","3")
C <- c("G1", "G2", "G2", "G2", "G3", "G3", "G3", "G4", "G4", "G4", "G4", 
       "G5", "G5", "G5","G6", "G6", "G7","G8","G8","G8")

df <- data.frame(A,B,C)

A   B   C
NT  1   G1
MCS 3   G2
MCS 3   G2
NT  3   G2
MCS 3   G3
MCS 3   G3
NT  3   G3
MCS 4   G4
MCS 4   G4
MCS 4   G4
NT  4   G4
MCS 3   G5
MCS 3   G5
NT  3   G5
MCS 2   G6
NT  2   G6
NT  1   G7
MCS 3   G8
MCS 3   G8
NT  3   G8

A 列代表物种。 B 列表示一个整数值,等于每组中的行数。 C 列代表唯一组。标准如下:如果 B > 1,则删除每个组/物种的最后一行。如果 B = 1,则 NT(或该组中的唯一行)应保留。这是我需要的样子。

A   B   C
NT  1   G1
MCS 3   G2
MCS 3   G2
MCS 3   G3
MCS 3   G3
MCS 4   G4
MCS 4   G4
MCS 4   G4
MCS 3   G5
MCS 3   G5
MCS 2   G6
NT  1   G7
MCS 3   G8
MCS 3   G8

new<- df %>% group_by(A, B) %>% slice(if(any(numb > 1)) 1:n())

上面是我运行过的最接近的代码,但它不会计算为整数或数字向量(这是我需要它做的)。我是这样做的:

new <- df %>% group_by(A, B) %>% 
              slice(if(any(B > 1)) 1 else 1:n())

但它摆脱了重复的值(所以我不想删除 A 列中的所有值 - 无论是否重复,都不是最后一行)。我运行的代码中是否缺少某些东西或可以实现此目的的另一种方法(理想情况下在 dplyr 中,但我会对所有方法感到好奇)?

【问题讨论】:

    标签: r


    【解决方案1】:
    df %>% group_by(C) %>% slice(if(n() > 1) 1:(n()-1) else 1)
    

    library(data.table)
    setDT(df)
    
    df[, if (.N > 1) head(.SD, -1) else .SD, by = C]
    

    或用于max speed(还顺便保持列顺序)

    df[df[, if (.N > 1) head(.I, -1) else .I, by = C]$V1]
    

    【讨论】:

    • 或者更复杂,确定要删除的行:df[ {w &lt;- df[, if (.N&gt;1L) .I[.N], by=C]$V1; if (length(w)) -w else TRUE } ] 或者类似以 w &lt;- df[!duplicated(C, fromLast=TRUE), which=TRUE] 开头的行,过滤到差异大于 1 的行,前提是已排序。
    • 谢谢,第一个代码运行良好。对于另外两个,我得到了一个(未使用的参数(by = C))错误。
    【解决方案2】:

    有了dplyr,我们也可以这样做

    library(dplyr)
    df %>%
         group_by(C) %>%
         slice(union(1, head(seq_len(n()), -1)))
    

    filter

    df %>%
       group_by(C) %>%
       filter(row_number() != n() | n()==1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-02
      • 2020-02-23
      • 2021-12-08
      • 2018-10-04
      • 1970-01-01
      • 2021-02-24
      • 2021-08-29
      • 2021-05-19
      相关资源
      最近更新 更多