2014-12-11 4 views
1

Мне нужно применить функцию к фреймворку данных, подмножество или сгруппировать по уникальным значениям.Применить функцию к dataframe на основе уникальных значений

Мои данные выглядит следующим образом:

FID FIX_NO ELK_ID ALTITUDE  XLOC YLOC DATE_TIME JulDate 
1 NA 5296 393 2260.785 547561.3 4771900  NA  140 
2 NA 5297 393 2254.992 547555.9 4771906  NA  140 
3 NA 5298 393 2256.078 547563.5 4771901  NA  140 
4 NA 5299 393 2247.047 547564.7 4771907  NA  140 
5 NA 5300 393 2264.875 547558.3 4771903  NA  140 
6 NA 5301 393 2259.496 547554.1 4771925  NA  140 
... 
24247 NA 4389 527 2204.047 558465.7 4775358  NA  161 
24248 NA 4390 527 2279.078 558884.1 4775713  NA  161 
24249 NA 4391 527 2270.590 558807.9 4775825  NA  161 
24250 NA 4392 527 2265.258 558732.2 4775805  NA  161 
24251 NA 4393 527 2238.375 558672.4 4775781  NA  161 
24252 NA 4394 527 2250.055 558686.6 4775775  NA  161 

Моя цель состоит в том, чтобы сделать новый data.frame путем случайного выбора 4 строк на каждой JulDate для каждого уникального ELK_ID. Если бы я сделать это вручную, для каждого уникального ELK_ID мой код выглядит следующим образом:

oneelk <- subset(dataset, ELK_ID == 393)
newdata <- do.call(rbind,lapply(split(oneelk,oneelk$JulDate), function(x)x[sample(1:nrow(x),4),]))

Есть > 40 ELK_IDs, так что мне нужно автоматизировать этот процесс. Пожалуйста, помогите!

+0

Используйте кнопку '{}', чтобы поместить данные в кодовые блоки. – jlhoward

ответ

2

Это решение для обработки данных.

library(data.table) 
setDT(dataset)[,.SD[sample(.N,4)],by=list(ELK_ID,JulDate)] 

# ELK_ID JulDate FID FIX_NO ALTITUDE  XLOC YLOC DATE_TIME 
# 1: 393  140 NA 5297 2254.992 547555.9 4771906  NA 
# 2: 393  140 NA 5299 2247.047 547564.7 4771907  NA 
# 3: 393  140 NA 5298 2256.078 547563.5 4771901  NA 
# 4: 393  140 NA 5300 2264.875 547558.3 4771903  NA 
# 5: 527  161 NA 4394 2250.055 558686.6 4775775  NA 
# 6: 527  161 NA 4392 2265.258 558732.2 4775805  NA 
# 7: 527  161 NA 4390 2279.078 558884.1 4775713  NA 
# 8: 527  161 NA 4393 2238.375 558672.4 4775781  NA 

Н.Б., это будет работать только тогда, когда существует по крайней мере 4 строки для каждой комбинации ELK_ID и JulDate.

+0

Благодарим за решение, к сожалению, похоже, что у меня есть несколько ELK_ID с менее чем 4 JulDates. – acb

+0

Затем используйте 'sample (.N, min (.N, 4))' вместо 'sample (.N, 4)'. Это займет случайную выборку, сколько бы ни было строк, до 4. – jlhoward

+0

Отлично, спасибо за настройку! – acb

1

Попытка разделить, используя обе колонки, возможно, split(dataset, dataset[, c("ELK_ID", "JulDate")])

2

Вы также можете создать индекс tapply, а затем просто подмножество (если ваш набор данных, который называется df)

indx <- unlist(tapply(seq_len(dim(df)[1L]), 
         df[, c("JulDate", "ELK_ID")], 
         function(x) sample(x, 4))) 
df[indx, ] 
+0

Когда я определяю indx, я получаю сообщение об ошибке «аргументы должны быть одинаковой длины». Я знаю, что для каждого значения ELK_ID есть соответствующее значение для JulDate, поэтому я не уверен, почему я получаю ошибку. – acb

+0

Причина, по которой вы получаете эту ошибку, состоит в том, что вы преобразовали свой набор данных в объект 'data.table' (сначала вы запустили код @jihoward). Если вы хотите, чтобы это сработало, запустите это в своем исходном наборе данных –

0

Мог бы также добавить dplyr также:

library(dplyr) 
newdf <- yourdata %>% 
      group_by(ELK_ID, JulDate) %>% 
      sample_n(4) 
+0

Я думаю, что это именно то, что я хочу, но мне нужно разрешение администратора обновить мою версию R, чтобы я мог получить доступ к dplyr. Позвольте вам знать, как это происходит! Благодаря! – acb

+0

Решение библиотеки (data.table) работало без необходимости обновлять мою версию R. Спасибо за помощь! – acb

Смежные вопросы