образцы строк data.table с разными условиями

У меня есть data.table с несколькими столбцами. Один из этих столбцов в настоящее время работает как «ключ» (например, keyb). Другой столбец (скажем, A) может содержать или не содержать данные. Я хотел бы предоставить вектор, который случайным образом выбирает две строки для каждого ключа, если этот ключ появляется в векторе, где 1 строка содержит данные в A, а другая - нет.

МРЭ:

#data.table
trys <- structure(list(keyb = c("x", "x", "x", "x", "x", "y", "y", "y", 
"y", "y"), A = c("1", "", "1", "", "", "1", "", "", "1", "")), .Names = c("keyb", 
"A"), row.names = c(NA, -10L), class = c("data.table", "data.frame"
))
setkey(trys,keyb)

#list with keys
list_try <- structure(list(a = "x", b = c("r", "y","x")), .Names = c("a", "b"))

Я мог бы, например, подмножить data.table на основе элементов, которые появляются в list_try:

trys[keyb %in% list_try[[2]]]

Моя первоначальная (и, вероятно, неэффективная идея) состояла в том, чтобы попытаться связать выборку из двух строк на ключ, где в столбце A есть данные или нет данных, а затем объединить. Но это не работает:

#here I was trying to sample rows based on whether A has data or not
#here for rows where A has no data
trys[keyb %in% list_try[[2]]][nchar(A)==0][sample(.N, 2), ,by = keyb]
#here for rows where A has data
trys[keyb %in% list_try[[2]]][nchar(A)==1][sample(.N, 2), ,by = keyb]

В этом случае моим ожидаемым результатом будут две таблицы data.table (одна для a и одна для b в list_try), по две строки на каждый появляющийся элемент: Таким образом, data.table из a будет иметь две строки (одна с данными и без них в A) и один из b, четыре строки (две с данными и две без данных в A).

Пожалуйста, дайте мне знать, если я могу сделать этот пост более понятным


person erasmortg    schedule 07.03.2016    source источник
comment
Не уверен, но может это trys[list_try[[2]], nomatch = 0L, sample(.I, 1L), by = .(keyb, A)]? V1 — индекс выборки строки   -  person David Arenburg    schedule 07.03.2016
comment
Для двух наборов данных может быть lapply(list_try, function(x) trys[x, nomatch = 0L, sample(.I, 1L), by = .(keyb, A)])   -  person David Arenburg    schedule 07.03.2016
comment
@DavidArenburg, это работает для моего примера набора данных, я адаптирую комментарий для своего фактического набора данных. Он отбрасывает все остальные столбцы (с соответствующей информацией) и по какой-то причине дает мне выборку из двух строк для столбца с данными вместо 1   -  person erasmortg    schedule 07.03.2016
comment
Если вы хотите сохранить другие столбцы, просто получите $V1, а затем подмножьте свои данные в соответствии с этим индексом, как, например, в trys[trys[list_try[[2]], nomatch = 0L, sample(.I, 1L), by = .(keyb, A)]$V1]. Кроме того, сколько уникальных значений у вас есть в A в ваших реальных данных? Если у вас более двух уникальных значений в A, вы можете изменить это значение на trys[list_try[[2]], nomatch = 0L, sample(.I, 1L), by = .(keyb, A != "")]$V1.   -  person David Arenburg    schedule 07.03.2016
comment
Хотите добавить в качестве ответа, @david? Это работает   -  person erasmortg    schedule 07.03.2016


Ответы (1)


Вы также можете добавить A к оператору by, преобразовав его в двоичный вектор, изменив на A != "", объединить с двоичным соединением (при добавлении nomatch = 0L для удаления несоответствий), вы можете затем выбрать из индекса строки .I по этим два агрегатора, а затем подмножество исходного набора данных

Для случая одного подмножества

trys[trys[list_try[[2]], nomatch = 0L, sample(.I, 1L), by = .(keyb, A != "")]$V1]
#    keyb A
# 1:    y 1
# 2:    y  
# 3:    x 1
# 4:    x  

Для более общего случая, когда вы хотите создать отдельные наборы данных в соответствии со списком ключей, вы можете легко встроить это в lapply

lapply(list_try, 
       function(x) trys[trys[x, nomatch = 0L, sample(.I, 1L), by = .(keyb, A != "")]$V1]) 
# $a
# keyb A
# 1:    x 1
# 2:    x  
# 
# $b
# keyb A
# 1:    y 1
# 2:    y  
# 3:    x 1
# 4:    x  
person David Arenburg    schedule 07.03.2016