我有一个data.table
,其中有属于多个分组的记录。我想计算两个变量属于同一组的记录数,其中分组变量可能包含一些NA。
以下示例数据:
library(data.table)
mydt <- data.table(id = c(1,2,3,4,5,6),
travel = c("no travel", "morocco", "algeria",
"morocco", "morocco", NA),
cluster = c(1,1,1,2,2,2))
> mydt
id travel cluster
1: 1 no travel 1
2: 2 morocco 1
3: 3 algeria 1
4: 4 morocco 2
5: 5 morocco 2
6: 6 <NA> 2
在上面的示例中,我想按集群计算有多少人前往每个目的地。
最初,我使用.N
表示法,如下所示:
mydt[, ndest1 := as.double(.N), by = c("cluster", "travel")]
> mydt
id travel cluster ndest1
1: 1 no travel 1 1
2: 2 morocco 1 1
3: 3 algeria 1 1
4: 4 morocco 2 2
5: 5 morocco 2 2
6: 6 <NA> 2 1
但是,将NA视为一个值-出于我的目的,此方法效果不佳,因为我后来想使用max(...)
来确定最多人旅行到的每个集群(上述集群2中的摩洛哥)是哪个目的地并且如果给定群集中有很多NA,则“ NA”将被错误地标记为最受欢迎的目的地。
然后我尝试改用sum()
,因为这很直观,也可以排除NA:
mydt[, ndest2 := sum(!is.na(travel)), by = c("cluster", "travel")]
> mydt
id travel cluster ndest1 ndest2
1: 1 no travel 1 1 1
2: 2 morocco 1 1 1
3: 3 algeria 1 1 1
4: 4 morocco 2 2 1
5: 5 morocco 2 2 1
6: 6 <NA> 2 1 0
这会给出错误的结果-经过进一步的测试,这似乎是因为我在sum(...)
中使用了与by
语句中的分组变量之一相同的逻辑语句变量
当我使用其他变量时,除了无法以这种方式排除NA之外,我将获得所需的结果:
mydt[, ndest3 := sum(!is.na(id)), by = c("cluster", "travel")]
> mydt
id travel cluster ndest1 ndest2 ndest3
1: 1 no travel 1 1 1 1
2: 2 morocco 1 1 1 1
3: 3 algeria 1 1 1 1
4: 4 morocco 2 2 1 2
5: 5 morocco 2 2 1 2
6: 6 <NA> 2 1 0 1
这使我想到两个问题:
by
之后用作分组变量?任何见解将不胜感激。
答案 0 :(得分:2)
您可以在NA
中排除i
mydt[!is.na(travel), ndest1 := .N, by = .(travel, cluster)][]
# id travel cluster ndest1
#1: 1 no travel 1 1
#2: 2 morocco 1 1
#3: 3 algeria 1 1
#4: 4 morocco 2 2
#5: 5 morocco 2 2
#6: 6 <NA> 2 NA