【问题标题】:in R, change dataframe column from the first occurence of a second column在 R 中,从第二列的第一次出现更改数据框列
【发布时间】:2026-01-24 09:20:03
【问题描述】:

我有一个类似这样的数据框:

set.seed(1004)
x <- c(sort(rnorm(40)),sort(rnorm(20)),
       sort(rnorm(40)),sort(rnorm(20)))
x[30:40] <- -x[30:40]+1
x[90:100] <- -x[90:100]+1

y <- c(rep('a',times = 60),rep('b',times = 60))
z <- 1:length(x)

df <- data.frame(z, x, y)

我想根据xy新建一个专栏。我想要的是,在每个y 子组(即示例中的“a”和“b”)中,x &gt; 0 的第一次出现,该额外列的下一行应该具有相同的值(因子)。而且,即使x &lt; 0 在第一次出现后再次出现。

最后我想要这样的东西:

df$y2 <- c(rep('0', times = 20), rep('1', times = 40), rep('0', times = 19), rep('1', times = 41))

到目前为止,我尝试过这个:

library(magrittr)
df %<>% 
  mutate(y2 = case_when(
    x < 0 ~ '0',
    x >= 0 ~ '1'
  ))

但我错过了一个论点,即使x 再次变为负数,y2 仍保持在“1”。

我想要的图形表示是:到目前为止我有这个:

虽然我想要这个:

【问题讨论】:

    标签: r dataframe find-occurrences


    【解决方案1】:
    df <- data.frame(z, x, y)
    df$y2 <- c(rep('0', times = 20), rep('1', times = 40), rep('0', times = 19), rep('1', times = 41))
    
    library(magrittr)
    df %<>% 
      group_by(y) %>% 
      mutate(y3 = cummax(ifelse(x < 0, 0, 1))) #by taking cummax, y3 will always be 1 after the first x > 0 for each group y
    
    table(df$y2 == df$y3, useNA = "always")
    
    TRUE <NA> 
     120    0 
    

    【讨论】:

    • cummax(x &gt;= 0)
    • 哦,是的,你是对的,我什至不需要ifelse()
    • 谢谢,因为我确实为这个可重现的例子回答了我的问题,所以我接受这个答案。但由于某种原因,它不适用于我的原始数据集(没有警告消息,只是所有 y3 等于 1)。我会尝试修复它,但感谢您提供cummax 功能。
    • 哦,我遇到了问题,group_by() 在我的情况下应该包含 2 列,而不仅仅是 1 列。
    • 您能针对这个其他问题提出一个新问题吗?
    【解决方案2】:

    在这里,我使用函数 Position 来查找满足特定条件的第一次出现的位置。在这种情况下 x > 0。 然后我创建一个向量,其中包含基于此位置的新列的值。

    library(dplyr)
    library(magrittr)
    
    createNewValues <- function(x){
      splitPoint <- Position(function(x) x>0, x)
      return(rep(c(0, 1), times = c(splitPoint-1, length(x)-splitPoint+1)))
    }
    
    df %<>% 
      group_by(y) %>% 
      mutate(y2 = createNewValues(x))
    

    【讨论】:

      最近更新 更多