两列的频率将一列中的 NA 计为零频率
Frequency of two columns counting NAs in one column as zero frequency
第 1 部分 我有以下数据 table。我想创建一个新列,其中包含每个 id
的出现次数,其中有任何样式值,NA
除外。主要问题是我不知道如何处理NA
。目前,当出现 NA
时,我得到的频率为 1.
id style
1 A
1 A
2 A
2 B
3 NA
4 A
4 C
5 NA
我尝试使用以下内容,但它仍然计算 NA
个值
dt[, allele_count := .N, by = list(pat_id, style)]
所需数据table如下:
id style count
1 A 2
1 A 2
2 A 2
2 B 2
3 NA 0
4 A 4
4 B 4
4 B 4
4 C 4
5 NA 0
Part2 我还希望能够添加另一列,其中包含具有特定样式值的每个 id
的出现次数。
id style count2
1 A 2
1 A 2
2 A 1
2 B 1
3 NA 0
4 A 1
4 B 2
4 B 2
4 C 1
5 NA 0
奖金问题:而不是像第 2 部分那样查看给定 style
值出现 id
的次数 ,如何计算每个 id
的 不同 style
值的数量,如下所示。
id style count3
1 A 1
1 A 1
2 A 2
2 B 2
3 NA 0
4 A 3
4 B 3
4 B 3
4 C 3
5 NA 0
这是一个可能的解决方案:
library(data.table)
dt <- data.table(id=c(1,1,2,2,3,4,4,5),
style=c('A','A','A','B',NA,'A','C',NA))
# count = number of ids having ALL styles defined
dt[, count := if(any(is.na(style))) 0L else .N, by = id]
# count2 = number of id-style occurrences (0 if style = NA)
dt[, count2 := if(is.na(style)) 0L else .N, by = .(id, style)]
> dt
id style count count2
1: 1 A 2 2
2: 1 A 2 2
3: 2 A 2 1
4: 2 B 2 1
5: 3 NA 0 0
6: 4 A 2 1
7: 4 C 2 1
8: 5 NA 0 0
奖金:
dt[, count3 := uniqueN(na.omit(style)), by = id]
> dt
id style count count2 count3
1: 1 A 2 2 1
2: 1 A 2 2 1
3: 2 A 2 1 2
4: 2 B 2 1 2
5: 3 NA 0 0 0
6: 4 A 2 1 2
7: 4 C 2 1 2
8: 5 NA 0 0 0
这是一种可能。基本上我们使用行子集来分配新列,然后在最后用零替换所有三个新列中的 NA
值。
nna <- !is.na(dt$style) ## so we don't have to call it four times
dt[nna, count := .N, by = id][nna, count2 := .N, by = .(id, style)][
nna, count3 := uniqueN(style), by = id][!nna, names(dt)[3:5] := 0L]
这导致
id style count count2 count3
1: 1 A 2 2 1
2: 1 A 2 2 1
3: 2 A 2 1 2
4: 2 B 2 1 2
5: 3 NA 0 0 0
6: 4 A 2 1 2
7: 4 C 2 1 2
8: 5 NA 0 0 0
或者您可以将其简化为以下内容,然后根据需要对列重新排序。
dt[nna, c("count", "count3") := .(.N, uniqueN(style)), by = id][
nna, count2 := .N, by = .(id, style)][!nna, names(dt)[3:5] := 0L]
请注意,此方法与其他发布的答案非常相似。我不确定这两者中哪一个是首选方法,行子集或 if()
语句。
第 1 部分 我有以下数据 table。我想创建一个新列,其中包含每个 id
的出现次数,其中有任何样式值,NA
除外。主要问题是我不知道如何处理NA
。目前,当出现 NA
时,我得到的频率为 1.
id style
1 A
1 A
2 A
2 B
3 NA
4 A
4 C
5 NA
我尝试使用以下内容,但它仍然计算 NA
个值
dt[, allele_count := .N, by = list(pat_id, style)]
所需数据table如下:
id style count
1 A 2
1 A 2
2 A 2
2 B 2
3 NA 0
4 A 4
4 B 4
4 B 4
4 C 4
5 NA 0
Part2 我还希望能够添加另一列,其中包含具有特定样式值的每个 id
的出现次数。
id style count2
1 A 2
1 A 2
2 A 1
2 B 1
3 NA 0
4 A 1
4 B 2
4 B 2
4 C 1
5 NA 0
奖金问题:而不是像第 2 部分那样查看给定 style
值出现 id
的次数 ,如何计算每个 id
的 不同 style
值的数量,如下所示。
id style count3
1 A 1
1 A 1
2 A 2
2 B 2
3 NA 0
4 A 3
4 B 3
4 B 3
4 C 3
5 NA 0
这是一个可能的解决方案:
library(data.table)
dt <- data.table(id=c(1,1,2,2,3,4,4,5),
style=c('A','A','A','B',NA,'A','C',NA))
# count = number of ids having ALL styles defined
dt[, count := if(any(is.na(style))) 0L else .N, by = id]
# count2 = number of id-style occurrences (0 if style = NA)
dt[, count2 := if(is.na(style)) 0L else .N, by = .(id, style)]
> dt
id style count count2
1: 1 A 2 2
2: 1 A 2 2
3: 2 A 2 1
4: 2 B 2 1
5: 3 NA 0 0
6: 4 A 2 1
7: 4 C 2 1
8: 5 NA 0 0
奖金:
dt[, count3 := uniqueN(na.omit(style)), by = id]
> dt
id style count count2 count3
1: 1 A 2 2 1
2: 1 A 2 2 1
3: 2 A 2 1 2
4: 2 B 2 1 2
5: 3 NA 0 0 0
6: 4 A 2 1 2
7: 4 C 2 1 2
8: 5 NA 0 0 0
这是一种可能。基本上我们使用行子集来分配新列,然后在最后用零替换所有三个新列中的 NA
值。
nna <- !is.na(dt$style) ## so we don't have to call it four times
dt[nna, count := .N, by = id][nna, count2 := .N, by = .(id, style)][
nna, count3 := uniqueN(style), by = id][!nna, names(dt)[3:5] := 0L]
这导致
id style count count2 count3
1: 1 A 2 2 1
2: 1 A 2 2 1
3: 2 A 2 1 2
4: 2 B 2 1 2
5: 3 NA 0 0 0
6: 4 A 2 1 2
7: 4 C 2 1 2
8: 5 NA 0 0 0
或者您可以将其简化为以下内容,然后根据需要对列重新排序。
dt[nna, c("count", "count3") := .(.N, uniqueN(style)), by = id][
nna, count2 := .N, by = .(id, style)][!nna, names(dt)[3:5] := 0L]
请注意,此方法与其他发布的答案非常相似。我不确定这两者中哪一个是首选方法,行子集或 if()
语句。