Подмножество неуравновешенное (реплицированное реплицирование), чтобы заполнить или сбалансировать набор данных в r
У меня есть набор данных, в котором неравное количество повторений. Я хочу подмножить данные, удалив те записи, которые являются неполными (т.е. Репликация меньше максимальной). Небольшой пример:
set.seed(123)
mydt <- data.frame (name= rep ( c("A", "B", "C", "D", "E"), c(1,2,4,4, 3)),
var1 = rnorm (14, 3,1), var2 = rnorm (14, 4,1))
mydt
name var1 var2
1 A 2.439524 3.444159
2 B 2.769823 5.786913
3 B 4.558708 4.497850
4 C 3.070508 2.033383
5 C 3.129288 4.701356
6 C 4.715065 3.527209
7 C 3.460916 2.932176
8 D 1.734939 3.782025
9 D 2.313147 2.973996
10 D 2.554338 3.271109
11 D 4.224082 3.374961
12 E 3.359814 2.313307
13 E 3.400771 4.837787
14 E 3.110683 4.153373
Резюме (mydt)
name var1 var2
A:1 Min. :1.735 Min. :2.033
B:2 1st Qu.:2.608 1st Qu.:3.048
C:4 Median :3.120 Median :3.486
D:4 Mean :3.203 Mean :3.688
E:3 3rd Qu.:3.446 3rd Qu.:4.412
Max. :4.715 Max. :5.787
Я хочу избавиться от A, B, E от данных, поскольку они неполны. Таким образом, ожидаемый результат:
name var1 var2
4 C 3.070508 2.033383
5 C 3.129288 4.701356
6 C 4.715065 3.527209
7 C 3.460916 2.932176
8 D 1.734939 3.782025
9 D 2.313147 2.973996
10 D 2.554338 3.271109
11 D 4.224082 3.374961
Обратите внимание, что набор данных большой, следующее может не иметь возможности:
mydt[mydt$name == "C",]
mydt[mydt$name == "D", ]
Ответы
Ответ 1
Вот решение, использующее data.table
:
library(data.table)
DT <- data.table(mydt, key = "name")
DT[, N := .N, by = key(DT)][N == max(N)]
# name var1 var2 N
# 1: C 3.070508 2.033383 4
# 2: C 3.129288 4.701356 4
# 3: C 4.715065 3.527209 4
# 4: C 3.460916 2.932176 4
# 5: D 1.734939 3.782025 4
# 6: D 2.313147 2.973996 4
# 7: D 2.554338 3.271109 4
# 8: D 4.224082 3.374961 4
.N
дает вам количество случаев для каждой группы и с помощью опции data.table
для сложных запросов вы можете сразу подмножество основываться на любом условии, которое вы хотите от этой новой переменной.
В базе R есть несколько подходов, наиболее очевидным из которых является table
:
with(mydt, mydt[name %in% names(which(table(name) == max(table(name)))), ])
Вероятно, менее распространенный, но похожий подход к предложению data.table
заключается в использовании ave()
:
counts <- with(mydt, as.numeric(ave(as.character(name), name, FUN = length)))
mydt[counts == max(counts), ]
Ответ 2
Вот простой способ, который не требует создания дополнительной структуры данных
tabl <- table(mydt[,1])
toRemove <- names(which(tabl < max(tabl)))
mydt[!mydt[,1] %in% toRemove, ]
# name var1 var2
# 4 C 3.070508 2.033383
# 5 C 3.129288 4.701356
# 6 C 4.715065 3.527209
# 7 C 3.460916 2.932176
# 8 D 1.734939 3.782025
# 9 D 2.313147 2.973996
# 10 D 2.554338 3.271109
# 11 D 4.224082 3.374961
В качестве одной строки:
mydt[!mydt[,1] %in% names(which(table(mydt[,1]) < max(table(mydt[,1])))), ]