数据集中的哪些变量在 id 内是常量
Which variables in dataset are constant within id
我有一个数据集,每个人都有一堆几乎重复的观察结果。我正在尝试准确确定每个特定 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
固定值,这些变量都不会改变。
让我们假设 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
任何值 > 1 的变量都有每个 carb
值的变化值。
编辑:
或者,我们可以将其扩展为 运行:
data.table(mtcars)[,lapply(.SD,uniqueN),by=carb
][,!"carb"][,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
只有当上述代码的输出是常量且等于 length(unique(id))
在相应的列中。 carb
有6个值,所以可以看出mtcars
中的变量none在carb
中是常量。此外,如果我们有很多 ID(在当前示例中有 >50,000),上述方法将很难直接解释。
坚持mtcars
,我们可以看到disp
中有几个变量是常量:
data.table(mtcars)[,lapply(.SD,uniqueN),by=disp
][,!"disp"][,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
在 disp
内是常数。
Michael,仍然不是 100% 清楚您想要的是什么,所以我将提出三种不同的解决方案,从至少有一个具有唯一值的组的所有列开始:
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],
all
) ) )
# [1] "cyl" "vs" "am" "gear"
请注意,由于组大小 == 1 可以解释为完全唯一或完全重复的特殊情况,所以这三者之间存在重叠。通过修改数据 table 调用中使用的函数,根据您的需要,应该很容易消除歧义。
我有一个数据集,每个人都有一堆几乎重复的观察结果。我正在尝试准确确定每个特定 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
固定值,这些变量都不会改变。
让我们假设 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
任何值 > 1 的变量都有每个 carb
值的变化值。
编辑:
或者,我们可以将其扩展为 运行:
data.table(mtcars)[,lapply(.SD,uniqueN),by=carb
][,!"carb"][,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
只有当上述代码的输出是常量且等于 length(unique(id))
在相应的列中。 carb
有6个值,所以可以看出mtcars
中的变量none在carb
中是常量。此外,如果我们有很多 ID(在当前示例中有 >50,000),上述方法将很难直接解释。
坚持mtcars
,我们可以看到disp
中有几个变量是常量:
data.table(mtcars)[,lapply(.SD,uniqueN),by=disp
][,!"disp"][,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
在 disp
内是常数。
Michael,仍然不是 100% 清楚您想要的是什么,所以我将提出三种不同的解决方案,从至少有一个具有唯一值的组的所有列开始:
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],
all
) ) )
# [1] "cyl" "vs" "am" "gear"
请注意,由于组大小 == 1 可以解释为完全唯一或完全重复的特殊情况,所以这三者之间存在重叠。通过修改数据 table 调用中使用的函数,根据您的需要,应该很容易消除歧义。