如何编写for循环或使用一个函数来检查数据中的组随时间的平等?
我有国会区的时间序列数据,如下面的小片一样安排,但当然有更多的数据:
dput(droplevels(head(CongressionalData[1:5],20)))
structure(list(state_dist = structure(c(1L, 1L, 1L, 1L, 1L, 2L,
2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L), .Label = c("AK_1",
"AL_1", "AL_2", "AL_3"), class = "factor"), electionyear = c(2002L,
2004L, 2006L, 2008L, 2010L, 2002L, 2004L, 2006L, 2008L, 2010L,
2002L, 2004L, 2006L, 2008L, 2010L, 2002L, 2004L, 2006L, 2008L,
2010L), cong = c(108L, 109L, 110L, 111L, 112L, 108L, 109L, 110L,
111L, 112L, 108L, 109L, 110L, 111L, 112L, 108L, 109L, 110L, 111L,
112L), name = structure(c(6L, 6L, 6L, 6L, 6L, 1L, 1L, 1L, 1L,
1L, 3L, 3L, 3L, 2L, 4L, 5L, 5L, 5L, 5L, 5L), .Label = c("BONNER",
"BRIGHT", "EVERETT", "ROBY", "ROGERS", "YOUNG"), class = "factor"),
republican = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L)), .Names = c("state_dist",
"electionyear", "cong", "name", "republican"), row.names = c(NA,
20L), class = "data.frame")
我试图只在区内进行比较,所以我想检查一个地区是否在共和党和民主代表之间切换。为简单起见,我想生成一个包含0或1的列表,用于切换或不切换。我的第一个想法是for循环:
group1 <- c()
for (i in 1:(nrow(CongressionalData) - 1)) {
if (CongressionalData$republican[i] == CongressionalData$republican[i+1]) {
group1 <- c(group1, 1)
}
else {
group1 <- c(group1, 0)
}
}
但是,这将每个地区的上次选举与下一个地区的第一次选举进行比较。
我在其他地方已经看到在R中使用for循环很少是一个好主意,但我对这些函数在这里工作的意义不大。
答案 0 :(得分:2)
您可以使用data.table
包进行此类转换。由于您要比较行之间的列,因此您需要shift
函数,在此情况下会生成 republican 列的滞后向量。然后Reduce
函数与==
将比较列的原始版本和滞后版本。如果它们相等,则返回true,否则返回false。 as.integer
函数将逻辑值强制转换为1
和0
。
library(data.table)
setDT(CongressionalData)[, group1 := as.integer(Reduce("==", shift(republican, n = 0:1, type = "lag"))), .(state_dist)]
CongressionalData
state_dist electionyear cong name republican group1
1: AK_1 2002 108 YOUNG 1 NA
2: AK_1 2004 109 YOUNG 1 1
3: AK_1 2006 110 YOUNG 1 1
4: AK_1 2008 111 YOUNG 1 1
5: AK_1 2010 112 YOUNG 1 1
6: AL_1 2002 108 BONNER 1 NA
7: AL_1 2004 109 BONNER 1 1
8: AL_1 2006 110 BONNER 1 1
9: AL_1 2008 111 BONNER 1 1
10: AL_1 2010 112 BONNER 1 1
11: AL_2 2002 108 EVERETT 1 NA
12: AL_2 2004 109 EVERETT 1 1
13: AL_2 2006 110 EVERETT 1 1
14: AL_2 2008 111 BRIGHT 0 0
15: AL_2 2010 112 ROBY 1 0
16: AL_3 2002 108 ROGERS 1 NA
17: AL_3 2004 109 ROGERS 1 1
18: AL_3 2006 110 ROGERS 1 1
19: AL_3 2008 111 ROGERS 1 1
20: AL_3 2010 112 ROGERS 1 1