如何基于时间变量识别data.frame中的唯一行和唯一观察

时间:2016-03-27 21:23:45

标签: r dataframe unique

我有以下数据:

d <- data.frame(id=c(1,2,3,4,5,6,7), 
             year=c(1999,1999,1999,2000,2000,2000,2000), 
             var1=c(1,1,2,1,4,1,8),
             var2=c(1,1,2,1,5,2,0),
             var3=c(0,0,0,0,7,0,0))

> d
  id year var1 var2 var3
1  1 1999    1    1    0
2  2 1999    1    1    0
3  3 1999    2    2    0
4  4 2000    1    1    0
5  5 2000    4    5    7
6  6 2000    1    2    0
7  7 2000    8    0    0

我想评估data.frame的每一行,并在名为&#39; comb&#39;的新变量中返回一个分数。

如果一行包含var1-var3之间的组合:

  • 前几年从未观察到(但元素是) - &gt; assign comb = 1
  • 包含前几年从未见过的元素 - &gt; assign comb = 2
  • 前几年从未观察到并且拥有一个新元素 - &gt; assign comb = 3
  • 在往年观察到的 - &gt; assign comb = 0

一些旁注:

  • 出现顺序无关紧要(1,1,2 == 1,2,1)
  • 同一年份的重复组合可能会被标记为相同

在示例数据中,这应该如下所示:

d2 <- data.frame(id=c(1,2,3,4,5,6,7), 
            year=c(1999,1999,1999,2000,2000,2000,2000), 
            var1=c(1,1,2,1,4,1,8),
            var2=c(1,1,2,1,5,2,0),
            var3=c(0,0,0,0,7,0,0),
            comb=c(3,3,3,0,3,1,2))
> d2
  id year var1 var2 var3 comb
1  1 1999    1    1    0    3
2  2 1999    1    1    0    3
3  3 1999    2    2    0    3
4  4 2000    1    1    0    0
5  5 2000    4    5    7    3
6  6 2000    1    2    0    1
7  7 2000    8    0    0    2

请注意,第二行被赋予comb = 3,因为它是我们观察到这些组合的第一年。如果此观察结果是年份= 200(如第4行),则会为其指定零。

这可能吗?非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

这可能是更好的方法,但这是一种可能的策略。首先,您可以创建一个var1...var3组合的字符串,如下所示:

> d2$var123 <- paste(d2$var1, d2$var2, d2$var3, sep="-")
> d2
  id year var1 var2 var3 var123
1  1 1999    1    1    0  1-1-0
2  2 1999    1    1    0  1-1-0
3  3 1999    2    2    0  2-2-0
4  4 2000    1    1    0  1-1-0
5  5 2000    4    5    7  4-5-7
6  6 2000    1    2    0  1-2-0
7  7 2000    8    0    0  8-0-0

此时,你可以简单地(1)循环所有元素; (2)检查var值中是否出现var123值或所有先前var1...var3列的列表,然后相应地分配comb值。这是一个伪代码:

d2$comb <- 0  # Initialize column
for (i in unique(d2$id)) {
    previous <- subset(d2, d2$id < i) # All the years before
    current <- subset(d2, d2$id == i) # The current row
    previous_vals <- unique(c(previous$var1, previous$var2, previous$var3)) 
    previous_combos <- unique(previous$var123)

    if (i$var1 %in% previous_vals | i$var1 %in% previous_vals... ) {
        d2$comb([d2$id==1] <- 1
    }
    if (i$var123) %in% previous_combos {
        d2$comb[d2$id==i] <- 0
    }
    .... # Rest of conditions here 
}