Объединить элементы списка в соответствии с общим значением фрейма данных
Продолжение этого вопроса здесь, хотя пример конкретный, это похоже на обобщаемое приложение, поэтому я думаю, что стоит отдельная тема:
Общий вопрос: как мне взять элементы в списке, которые соответствуют значению в исходном фрейме данных, и объединить их в соответствии с этим значением в исходном фрейме данных, особенно если элементы списка имеют разную длину?
В этом примере у меня есть фрейм данных с двумя группами, каждая из которых отсортирована по дате. В конечном итоге я хочу получить блок данных, упорядоченный по дате, который содержит только соответствующие метрики для каждого сегмента. Если определенный сегмент не имеет данных на определенную дату, он получает 0.
Вот некоторые фактические данные:
structure(list(date = structure(c(15706, 15707, 15708, 15709,
15710, 15706, 15707, 15708), class = "Date"), segment = structure(c(1L,
1L, 1L, 1L, 1L, 2L, 2L, 2L), .Label = c("abc", "xyz"), class = "factor"),
a = c(76L, 92L, 96L, 76L, 80L, 91L, 54L, 62L), x = c(964L,
505L, 968L, 564L, 725L, 929L, 748L, 932L), k = c(27L, 47L,
36L, 40L, 33L, 46L, 30L, 36L), value = c(6872L, 5993L, 5498L,
5287L, 6835L, 6622L, 5736L, 7218L)), .Names = c("date", "segment",
"a", "x", "k", "value"), row.names = c(NA, -8L), class = "data.frame")
Так что для сегмента "abc" Я ПРОСТО забочусь о (value/a) относительно его эталона 75. а для сегмента "xyz" Я ПРОСТО забочусь о (k/x) относительно его эталона 0.04.
В конечном итоге я хочу, чтобы данные выглядели так:
date abc xyz
1 2013-01-01 0.21 0.24
2 2013-01-02 -0.13 0.00
3 2013-01-03 -0.24 -0.03
4 2013-01-04 -0.07 0.00
5 2013-01-05 0.14 0.00
Где, поскольку "xyz" имел информацию только за 2013-01-01 - 2013-01-03, он получает 0 для всех после.
Как я дошел до этого пункта было:
определить аргументы для передачи в mapply
splits <- split(test, test$segment)
metrics <- c("ametric","xmetric")
benchmarks <- c(75,0.04)
и функция, чтобы получить производительность по сравнению с эталоном
performance <- function(splits,metrics,benchmarks){
(splits[,metrics]/benchmarks)-1
}
Передайте это mapply:
temp <- mapply(performance, splits, metrics, benchmarks)
Проблема в том, что, поскольку разбиения были разной длины, выходные данные выглядят так:
summary(temp)
Length Class Mode
abc 5 -none- numeric
xyz 3 -none- numeric
Есть ли способ ввести даты из исходного фрейма данных для каждого разделения и объединить в соответствии с этими датами (с 0, где нет данных)?
1 ответ
Вам просто нужно установить SIMPLIFY=FALSE
аргумент mapply
тогда вы можете использовать do.call
с rbind
поместить все обратно в один фрейм данных:
> temp <- mapply(performance, splits, metrics, benchmarks)
> do.call('rbind',mapply(cbind, splits, performance=temp, SIMPLIFY=FALSE))
date segment a x k value performance
abc.1 2013-01-01 abc 76 964 27 6872 1.333333e-02
abc.2 2013-01-02 abc 92 505 47 5993 2.266667e-01
abc.3 2013-01-03 abc 96 968 36 5498 2.800000e-01
abc.4 2013-01-04 abc 76 564 40 5287 1.333333e-02
abc.5 2013-01-05 abc 80 725 33 6835 6.666667e-02
xyz.6 2013-01-01 xyz 91 929 46 6622 2.322400e+04
xyz.7 2013-01-02 xyz 54 748 30 5736 1.869900e+04
xyz.8 2013-01-03 xyz 62 932 36 7218 2.329900e+04