#r #dplyr
#r #dplyr
Вопрос:
Я пытаюсь изменить порядок набора данных с несколькими тысячами наблюдений (чтобы в конечном итоге использовать функцию drm в пакете DRC), и я устал делать это в Excel. Внутри фрейма данных я хочу добавить время «начала» и «окончания» (с точностью до inf) на основе интервалов, найденных в векторе внутри df. Это означает, что в конечном итоге мне пришлось бы добавить наблюдение (строку), где время последнего «окончания» равно inf. Для этой последней строки (той, что с inf) мне также нужно вычесть общее значение «value» из произвольного числа (в моем примере ниже это будет 50). Все это сгруппировано по двум переменным («Name» и «Rep» в моем примере). Я надеюсь, что есть решение с использованием group_by
, но, честно говоря, я буду вне себя от радости при любом решении!
У меня есть набор данных, который выглядит следующим образом;
# data
names<-c(rep("Luke",30), rep("Han", 30), rep("Leia", 30), rep("OB1", 30))
reps<-c(rep("A", 10), rep("B", 10), rep("C", 10))
time<-rep(seq(1:10), 4)
value<-rep(sample(0:5,10,replace=T), 4)
df<-data.frame(names, reps, time, value)
но нужно, чтобы это выглядело так;
Пример структуры данных, которая мне нужна.
Я в растерянности. Пожалуйста, помогите!
Ответ №1:
Если я вас правильно понял, мы можем сделать
library(dplyr)
df1 <- df %>%
group_by(names, reps) %>%
mutate(start = lag(time, default = 0),
end = time)
bind_rows(df1, df1 %>%
group_by(names, reps) %>%
summarise(start = last(time),
end = Inf,
value = sum(value))) %>%
select(-time) %>%
arrange(names, reps)
# names reps value start end
# <fct> <fct> <int> <dbl> <dbl>
# 1 Han A 2 0 1
# 2 Han A 2 1 2
# 3 Han A 1 2 3
# 4 Han A 1 3 4
# 5 Han A 3 4 5
# 6 Han A 2 5 6
# 7 Han A 0 6 7
# 8 Han A 2 7 8
# 9 Han A 2 8 9
#10 Han A 5 9 10
#11 Han A 20 10 Inf
#.....
Комментарии:
1. Спасибо Ронак Шоу! Я получаю следующую ошибку;
Error in select(., -time) : unused argument (-time)
Есть идеи относительно того, почему?2. @Dustin скорее всего, это связано с конфликтом в использовании
select
. Попробуйте перезапустить R или явно использоватьdplyr::select(-time)
вместоselect(-time)
3. да, это была проблема, спасибо. Это отлично работает и с моим реальным набором данных! Единственное изменение, которое я внес, — это добавление «50-» перед «value = sum (значение), чтобы строка читалась,
50 - value = sum(value)
. Большое вам спасибо!
Ответ №2:
Мы можем сделать это, data.table
shift
указав ‘time’, добавив ‘Inf’ в конце ‘time’, чтобы создать end
разницу в 50 от sum
‘value’ для ‘value’ после группировки по ‘именам’ и ‘представлениям’
library(data.table)
setDT(df)[, {stL <- last(time)
enL <- Inf
vL <- 50- sum(value)
.(start = c(shift(time, fill = 0), stL),
end = c(time, enL),
value = c(value, vL))}, .(names, reps)]
# names reps start end value
# 1: Luke A 0 1 0
# 2: Luke A 1 2 3
# 3: Luke A 2 3 3
# 4: Luke A 3 4 4
# 5: Luke A 4 5 0
# ---
#128: OB1 C 6 7 3
#129: OB1 C 7 8 0
#130: OB1 C 8 9 2
#131: OB1 C 9 10 5
#132: OB1 C 10 Inf 27