数据集中的哪些变量在id中是常量

时间:2015-03-04 15:52:54

标签: r data.table

我有一个数据集,每个人都有一堆近乎重复的观察结果。我正在尝试确定哪些变量在每个特定ID的行间有所变化。

我从检查开始:

dt[ , count := .N, by = id][count > 1, ]

(也使用headtail),但有27000(总)重复观察 - 检查无法确定哪些变量正在发生变化。

有什么比蛮力方法更好的吗? 特别是我希望避免循环,但我看不出如何......

dt[ , count := .N, by = id]
for (var in setdiff(names(dt), c("id", "count"))){
  if (nrow(dt[ , list(.N, count), by = c("id", var)][N < count, ]) > 0){
    print(var)
  }
}

修改

这是一个澄清的示例数据集:

set.seed(2304)
DT <- data.table(a = rep(sample(5), each = 3),
                 b = sample(15),
                 c = rep(LETTERS[1:5], each = 3),
                 d = rnorm(15),
                 e = rep(6:10, each = 3),
                 f = 15:1,
                 grp = paste0("Group ", rep(1:5, each = 3)))

期望的输出:

c("a", "c", "e")

因为任何固定值grp的变量都没有变化。

2 个答案:

答案 0 :(得分:5)

让我们假装mtcars$carb是我们的id。然后,对于每个ID的每个数字,我们想要找出有多少不同的gear值:

data.table(mtcars)[, lapply(.SD, function(x) length(unique(x))), by=carb]

可生产

   carb mpg cyl disp hp drat wt qsec vs am gear
1:    4   8   2    8  7    8  9   10  2  2    3
2:    1   7   2    7  6    6  7    7  1  2    2
3:    2   9   2   10  8    9 10   10  2  2    3
4:    3   3   1    1  1    1  3    3  1  1    1
5:    6   1   1    1  1    1  1    1  1  1    1
6:    8   1   1    1  1    1  1    1  1  1    1

任何值为&gt;的变量1具有每个carb值的更改值。


编辑:

或者,我们可以通过运行:

来扩展它
data.table(mtcars)[,lapply(.SD,uniqueN),by=carb
                   ][,!"carb",with=F][,lapply(.SD,table)]

   mpg cyl disp hp drat wt qsec vs am gear
1:   2   3    3  3    3  2    2  4  3    3
2:   1   3    1  1    1  1    1  2  3    1
3:   1   3    1  1    1  1    1  4  3    2
4:   1   3    1  1    1  1    2  2  3    3
5:   1   3    3  3    3  1    2  4  3    1

这有一个优点(对于此示例数据集不明显),只有上述代码的输出是常量且等于{{1}时,给定列在ID(carb此处)内是常量。在相应的列中。 length(unique(id))有6个值,因此我们可以看到carb中变量的 none mtcars内是常量。此外,如果我们有很多ID(在当前示例中我有> 50,000),上述方法将更难直接解释。

坚持使用carb,我们可以看到mtcars内有一些常量变量:

disp

因此,data.table(mtcars)[,lapply(.SD,uniqueN),by=disp ][,!"disp",with=F][,lapply(.SD,table)] mpg cyl hp drat wt qsec vs am gear carb 1: 24 27 26 26 24 23 27 27 27 26 2: 2 27 1 1 2 3 27 27 27 1 3: 1 27 26 26 1 1 27 27 27 26 vsamgear内保持不变。

答案 1 :(得分:0)

迈克尔,仍然没有完全清楚你所追求的是什么,所以我建议三种不同的解决方案,从至少有一个具有独特价值的群体的所有列开始:

names(
  Filter(
    identity,
    colSums(MT[, lapply(.SD, function(x) uniqueN(x) == .N), by=disp])  
) )[-1]

# [1] "mpg"  "cyl"  "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"

所有具有每个组唯一值的列

names(
  Filter(
    `!`,
    colSums(MT[, lapply(.SD, function(x) uniqueN(x) != .N), by=disp])  
) )

# [1] "qsec"

在每个组中完全重复的所有变量:

names(
  Filter(
    identity,
    lapply(
      MT[, lapply(.SD, function(x) uniqueN(x) == 1), by=disp][, -1, with=F], 
      all
) ) )

# [1] "cyl"  "vs"   "am"   "gear"

请注意,所有三者之间都存在重叠,因为特殊情况下,组大小== 1可以解释为完全唯一或完全重复。根据你想要的东西修改数据表调用中使用的函数,这应该很容易被歧视。