R中的虚拟变量"switch-point"

Dummy variable "switch-point" in R

我有一个虚拟变量作为我数据集中许多条件的标志。 我不知道如何编写一个函数来标记标志假定 "final switch" 的位置 -- 一个不会因数据框的其余部分而改变的值。 在下面的示例中,第 7 次观察后的所有内容都是 "y"。

  dplyr::tibble(
    observation = c(seq(1,10)),
    crop = c(runif(3,1,25),
              runif(1,50,100),
              runif(2,1,10),
              runif(4,50,100)),
    flag = c(rep("n", 3),
             rep("y", 1),
             rep("n", 2),
             rep("y", 4)))

产生:

   observation  crop flag 
         <int> <dbl> <chr>
 1           1 13.3  n    
 2           2  4.34 n    
 3           3 17.1  n    
 4           4 80.5  y    
 5           5  9.62 n    
 6           6  8.39 n    
 7           7 92.6  y    
 8           8 74.1  y    
 9           9 95.3  y    
10          10 69.9  y    

我已经尝试创建第二个标志来标记每个开关和 returns "final" switch/flag 变量,但是在我的整个数据帧上这可能非常低效。欢迎和赞赏任何建议。

实现此目的的一种方法可能是创建一个标志,该标志对标志切换的出现次数进行累积求和。

cumsum_na <- function(x){
  x[which(is.na(x))] <- 0
  return(cumsum(x))
}

df <- dplyr::tibble(
    observation = c(seq(1,10)),
    crop = c(runif(3,1,25),
              runif(1,50,100),
              runif(2,1,10),
              runif(4,50,100)),
    flag = c(rep("n", 3),
             rep("y", 1),
             rep("n", 2),
             rep("y", 4)))

df %>%
  mutate(flag2 = ifelse(flag != lag(flag), 1, 0) %>%
               cumsum_na)

# A tibble: 10 x 4
   observation  crop flag  flag2
         <int> <dbl> <chr> <dbl>
 1           1 12.1  n         0
 2           2 11.2  n         0
 3           3  4.66 n         0
 4           4 61.6  y         1
 5           5  6.00 n         2
 6           6  9.54 n         2
 7           7 67.6  y         3
 8           8 86.7  y         3
 9           9 91.6  y         3
10          10 84.5  y         3

然后您可以使用 flag2 列做任何您需要的事情(例如,过滤最大值,取第一行,这将为您提供第一次出现的常量状态)。

我先统计所有的"n",当遇到最后的"n"时,我得到下一个obs的索引

i=0
j=1
while (i<table(df$flag)["n"]) {
  if (as.character(df[j,3]) =="n" ) {
    i=i+1
    j=j+1
  } else j=j+1
}

您正在寻找 j

我们可以利用 rleid 来自 data.table

library(data.table)
setDT(df)[, flag2 := rleid(flag)]
df
#    observation      crop flag flag2
# 1:           1 21.472985    n     1
# 2:           2 21.563190    n     1
# 3:           3  1.393184    n     1
# 4:           4 88.422562    y     2
# 5:           5  6.383627    n     3
# 6:           6  8.484030    n     3
# 7:           7 86.998953    y     4
# 8:           8 62.220592    y     4
# 9:           9 93.141503    y     4
#10:          10 96.006885    y     4