#r #data.table
#r #data.table
Вопрос:
Это мои входные данные
key col_a col_b
a QQQ <NA>
a QQC <NA>
b <NA> ACQ
b <NA> ACQ
Я хотел бы создать этот вывод
key col_a col_b
a 2 0
b 0 1
Я пытался сделать это с помощью length(unique(x $ col_a)), но он считает NA как значения
Я создаю этот объект с помощью data.tables, и он исходит из инструкции ifelse().
Могу ли я изменить значение, которое я ввожу в инструкцию ifelse, на что-то другое или считать уникальные, игнорируя NAs?
Ответ №1:
Для каждого key
мы можем узнать уникальные значения в столбцах с n_distinct
library(dplyr)
df %>%
group_by(key) %>%
summarise(across(col_a:col_b, n_distinct, na.rm = TRUE))
В data.table
это можно сделать как :
library(data.table)
setDT(df)[, lapply(.SD, uniqueN, na.rm = TRUE), key, .SDcols = col_a:col_b]
key col_a col_b
1: a 2 0
2: b 0 1
Комментарии:
1. Потрясающе, я отмечу, что n_distinct также имеет
na.rm=T
2. Это даже лучше. Спасибо. Я обновил ответ, чтобы включить это.
3. Что такое .SD во второй части?
4. В
data.table
вы можете указать столбцы, к которым хотите применить функцию с.SDcols
. Вlapply
мы используем.SD
для ссылки на эти столбцы.
Ответ №2:
Мы можем использовать base R
методы для этого
aggregate(. ~ key, df, FUN = function(x)
length(unique(na.omit(x))), na.action = NULL)
# key col_a col_b
#1 a 2 0
#2 b 0 1
Или с tidyverse
использованием анонимной функции
library(dplyr)
df %>%
group_by(key) %>%
summarise(across(everything(), ~ n_distinct(., na.rm = TRUE)))
данные
df <- structure(list(key = c("a", "a", "b", "b"), col_a = c("QQQ",
"QQC", NA, NA), col_b = c(NA, NA, "ACQ", "ACQ")),
class = "data.frame", row.names = c(NA,
-4L))