我有一个数据集,每个人都有一堆近乎重复的观察结果。我正在尝试确定哪些变量在每个特定ID的行间有所变化。
我从检查开始:
dt[ , count := .N, by = id][count > 1, ]
(也使用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)
}
}
这是一个澄清的示例数据集:
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
的变量都没有变化。
答案 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
,vs
和am
在gear
内保持不变。
答案 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可以解释为完全唯一或完全重复。根据你想要的东西修改数据表调用中使用的函数,这应该很容易被歧视。