Сэмплирование данных на основе минимального и максимального ненулевых элементов в строках - PullRequest
0 голосов
/ 04 июля 2019

У меня есть счетная матрица с множеством нулевых элементов:

my.matrix <- as.data.frame(matrix(rbinom(100 * 1000, 1, 0.5), ncol = 100, nrow = 1000))

(в действительности диапазон ненулевых целых чисел составляет от 1 до 12 000, но я не смог найти лучшего примера. Мой набор данных не содержит только 0 и 1).

Я бы хотел случайным образом выбрать n строк (например, n = 100) с не менее чем x n, но не более чем y ненулевыми элементами:

n = number of randomly selected rows 
x = minimum amount of non-zero elements in a row
y = maximum amount of non-zero elements in a row

Как это сделать? Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 04 июля 2019

Установка начального числа для воспроизводимых случайных данных:

set.seed(2)
my.matrix <- as.data.frame(matrix(rbinom(100 * 1000, 1, 0.5), ncol = 100, nrow = 1000))

Функции типа apply и rowSums преобразуют данные в matrix.Если таковые имеются, если у вас есть включенные столбцы character, то все будет преобразовано, и все может работать не так, как вы хотели бы.Использование isnum просто для того, чтобы убедиться, что вы случайно не включили его (даже если в этом фактическом примере данных нет ничего неправильного):

isnum <- sapply(my.matrix, is.numeric)
sums <- rowSums(my.matrix[,isnum] != 0)
head(sums)
# [1] 51 60 53 45 42 56
table(sums)
# sums
# 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 
#  2  2  1  7 11 20 21 37 36 49 46 64 72 71 59 79 72 77 76 52 48 33 21 14 11 10 
# 62 63 64 70 
#  1  5  2  1 

Отсюда просто установите поднабор диапазона вручную.

my.matrix[ 37 < sums & sums < 40, 1:4 ]
#     V1 V2 V3 V4
# 69   0  0  1  1
# 202  1  0  0  1
# 228  0  1  0  0
# 293  1  0  1  0
# 306  0  1  0  0
# 363  0  1  1  0
# 810  0  0  1  1
# 890  1  0  1  1

Вы также можете использовать dplyr::between или data.table::between для более краткого кода, хотя он не добавляет никаких возможностей по этому поводу.

Что касается выборки, то это прямая выборка один разу вас есть эта информация:

ind <- which(37 < sums & sums < 40)
ind <- sample(ind, min(length(ind), 100))
my.matrix[ ind, 1:4 ]
#     V1 V2 V3 V4
# 363  0  1  1  0
# 202  1  0  0  1
# 228  0  1  0  0
# 890  1  0  1  1
# 306  0  1  0  0
# 69   0  0  1  1
# 810  0  0  1  1
# 293  1  0  1  0

Я сделал max(...) на случай, если у вас будет меньше , чем 100 в вашем результирующем векторе.Без max вы можете увидеть cannot take a sample larger than the population when 'replace = FALSE'.

1 голос
/ 04 июля 2019

Если ваши данные являются числовыми, то придерживайтесь матрицы и не приводите ее в массив данных.Преобразование типов сопряжено с вычислительными затратами, и в этом случае датафрейм не дает очевидного преимущества.Используя немного отличающиеся данные:

set.seed(12345)
my.matrix <- matrix(sample(c(sample.int(12000, 90000, T), rep(0, 10000))),
                    ncol = 100,
                    nrow = 1000
                    )

Получить суммы строк логической матрицы, созданной my.matrix != 0, которая равна TRUE для ненулевых значений.Затем установите верхний и нижний пороги, проведите сравнение в which, чтобы получить индексы для всех строк, которые содержат не менее x и не более y ненулевых значений, нарисуйте образец n = 100 из этого,и использовать полученные индексы для поднабора вашего фрейма данных:

rs <- rowSums(my.matrix != 0)

x <- 85 # lower threshold
y <- 90 # upper threshold

my.matrix[sample(which(rs >= x & rs <= y), 100),]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...