基于相似重复出现的条件列创建

Conditional column creation based on similar repetitive occurrence

我有一个数据集

year <- c(2001:2015) 
id <- rep(c("a", "b", "c"), 5 )
status <- c(0, 1, 1, 0, 2,1,0, 1, 3, 0, 2, 0, 0, 0, 1 )
dt<- data.frame(year, id, status)

Hare id a, b, c,在 5 个不同的年份重复 5 次。现在我想创建一个名为“fact”的新列,如果所有年份的任何 id 具有相同的状态,则其值为 1,否则为 0。在这种情况下,相应行中的 id a 将为 1。数据集看起来像

year <- c(2001:2015)
id <- rep(c("a", "b", "c"), 5 )
status <- c(0, 1, 1, 0, 2,1,0, 1, 3, 0, 2, 0, 0, 0, 1 )
fact <- c(1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0)
dt<- data.frame(year, id, status, fact)

注意:在我的真实数据集中,有 280 万个观测值,每个 id 在所有年份都不会重复。

我曾尝试使用 case_when 解决此问题,但无法得出富有成效的结果。 非常感谢您的帮助。 谢谢

这个有用吗:

library(dplyr)
dt %>% group_by(id) %>% mutate(fact = case_when(n_distinct(status) == 1 ~ 1, TRUE ~ 0))
# A tibble: 15 x 4
# Groups:   id [3]
    year id    status  fact
   <int> <fct>  <dbl> <dbl>
 1  2001 a          0     1
 2  2002 b          1     0
 3  2003 c          1     0
 4  2004 a          0     1
 5  2005 b          2     0
 6  2006 c          1     0
 7  2007 a          0     1
 8  2008 b          1     0
 9  2009 c          3     0
10  2010 a          0     1
11  2011 b          2     0
12  2012 c          0     0
13  2013 a          0     1
14  2014 b          0     0
15  2015 c          1     0

您可以使用 ave 检查状态组中的 variance 是否为零。 + 将布尔值转换为整数。

transform(dt, fact=+(ave(status, id, FUN=var) == 0))
#    year id status fact
# 1  2001  a      0    1
# 2  2002  b      1    0
# 3  2003  c      1    0
# 4  2004  a      0    1
# 5  2005  b      2    0
# 6  2006  c      1    0
# 7  2007  a      0    1
# 8  2008  b      1    0
# 9  2009  c      3    0
# 10 2010  a      0    1
# 11 2011  b      2    0
# 12 2012  c      0    0
# 13 2013  a      0    1
# 14 2014  b      0    0
# 15 2015  c      1    0

一个data.table选项

setDT(dt)[, fact := +(uniqueN(status) == 1), id]

给予

> dt
    year id status fact
 1: 2001  a      0    1
 2: 2002  b      1    0
 3: 2003  c      1    0
 4: 2004  a      0    1
 5: 2005  b      2    0
 6: 2006  c      1    0
 7: 2007  a      0    1
 8: 2008  b      1    0
 9: 2009  c      3    0
10: 2010  a      0    1
11: 2011  b      2    0
12: 2012  c      0    0
13: 2013  a      0    1
14: 2014  b      0    0
15: 2015  c      1    0