我有一个数据集,每个人都有一堆近乎重复的观察结果.我正在尝试确定哪些变量在每个特定ID的行间有所变化.
我从检查开始:
dt[ , count := .N, by = id][count > 1, ]
Run Code Online (Sandbox Code Playgroud)
(也使用head和tail),但有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)
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个示例数据集,以阐明:
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)))
Run Code Online (Sandbox Code Playgroud)
期望的输出:
c("a", "c", "e")
Run Code Online (Sandbox Code Playgroud)
因为这些变量不会因任何固定值而改变grp.
让我们假装mtcars$carb是我们的id.然后,对于每个id的每个数字,我们想要找出gear有多少个不同的值:
data.table(mtcars)[, lapply(.SD, function(x) length(unique(x))), by=carb]
Run Code Online (Sandbox Code Playgroud)
产生
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
Run Code Online (Sandbox Code Playgroud)
值> 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
Run Code Online (Sandbox Code Playgroud)
这具有以下优点(对于此样本数据集不明显),只要carb上述代码的输出是常量且等于length(unique(id))相应列,给定列在ID(此处)内是恒定的.有6个值carb,因此我们可以看到其中没有任何变量mtcars是恒定的carb.此外,如果我们有很多ID(在当前示例中我有> 50,000),上述方法将更难直接解释.
坚持下去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
Run Code Online (Sandbox Code Playgroud)
因此,vs和am,并且gear在内disp.