Перераспределить результаты списка во фрейм данных r

Я делаю выборку всех значений одного столбца моего фрейма данных в зависимости от другого столбца. Для этого я использую tapply.

ex <- data.frame(
loc = c("1", "1", "2", "2", "2", "3", "3"),
sp = c("a", "b", "b", "c", "d", "a", "d"))
ex

all_sp <- unique(ex[, "sp"])
all_sp <- data.frame(all_sp)

ex$sp_random <- ""

sp_rand <- tapply(ex$sp_random, ex$loc, function(x) 
base::sample(all_sp$all_sp, size = length(x), replace = FALSE, prob = NULL))

Теперь я хотел бы поместить список sp_rand в исходный фрейм данных ex, но я не знаю, как это сделать правильно.

Единственный способ, который я нашел, - изменить порядок столбца ex следующим образом:

ex <- ex[order(ex$loc), ]
ex$sp_random <- as.character(unlist(sp_rand))
ex

но order довольно медленный с кадрами больших данных.


person P. Denelle    schedule 16.12.2015    source источник
comment
В чем конкретно заключается ваш вопрос/проблема?   -  person Heroka    schedule 16.12.2015
comment
Я хотел бы получить результат sp_rand в моем исходном фрейме данных ex. Но tapply дал мне список, и я не могу найти эффективный способ поместить его обратно в исходный фрейм данных.   -  person P. Denelle    schedule 16.12.2015


Ответы (3)


Мы можем попробовать data.table. Мы преобразуем «data.frame» в «data.table» (setDT(ex)), сгруппированные по «loc», мы получаем sample из levels(sp) и назначаем (:=) его «sp_random».

library(data.table)
setDT(ex)[, sp_random := sample(levels(sp), .N),by = loc]
person akrun    schedule 16.12.2015

Если я понимаю ваш вопрос, вы можете сделать это с помощью dplyr:

library(dplyr)
ex %>%
  group_by(loc) %>%
  mutate(sp_random = sample(levels(sp), n()))
person user2802241    schedule 16.12.2015

Я, вероятно, не понял вашей проблемы, но почему бы и вам не сделать:

ex <- data.frame(loc = c("1", "1", "2", "2", "2", "3", "3"),
    sp = c("a", "b", "b", "c", "d", "a", "d"))

spz <- unique(ex$sp)
ex$sp_random <- unlist(tapply(ex$sp, ex$loc, function(x) sample(spz,length(x))))
person Vongo    schedule 16.12.2015