У меня есть фрейм данных с результатами для определенных инструментов, и я хочу создать новый столбец, который содержит итоги каждой строки. Поскольку у меня разное количество инструментов каждый раз, когда я запускаю анализ новых данных, мне нужна функция для динамического вычисления нового столбца с помощью итоговой суммы.
Для моей проблемы вот как выглядит мой фрейм данных:
Type Value
1 A 10
2 A 15
3 A 20
4 A 25
5 B 30
6 B 40
7 B 50
8 B 60
9 B 70
10 B 80
11 B 90
Моя цель - достичь следующего:
A B Total
1 10 30 40
2 15 40 55
3 20 50 70
4 25 60 85
5 70 70
6 80 80
7 90 90
Я пробовал различные методы, но этот способ наиболее перспективен:
myList <- list(a = c(10, 15, 20, 25), b = c(30, 40, 50, 60, 70, 80, 90))
tmpDF <- data.frame(sapply(myList, '[', 1:max(sapply(myList, length))))
> tmpDF
a b
1 10 30
2 15 40
3 20 50
4 25 60
5 NA 70
6 NA 80
7 NA 90
totalSum <- rowSums(tmpDF)
totalSum <- data.frame(totalSum)
tmpDF <- cbind(tmpDF, totalSum)
> tmpDF
a b totalSum
1 10 30 40
2 15 40 55
3 20 50 70
4 25 60 85
5 NA 70 NA
6 NA 80 NA
7 NA 90 NA
Несмотря на то, что этому способу удалось объединить два фрейма данных различной длины, функция ‘rowSums’ в этом примере выдает неверные значения. Кроме того, мои исходные данные не представлены в виде списка, поэтому я не могу применить такое «решение».
Мне кажется, я слишком усложняю эту проблему, поэтому мне было интересно, как я могу ...
- Подмножество данных из фрейма данных на основе «Типа»,
- Вставить эти отдельные подмножества различной длины в новый фрейм данных,
- Добавьте столбец «Всего» к этому фрейму данных, который является правильной суммой
отдельные подмножества.
Дополнительным осложнением этой проблемы является то, что это должно быть сделано в функции или иным динамическим способом, так что мне не нужно вручную устанавливать десятки «типов» (A, B, C и и так далее) в моем фрейме данных.
Вот то, что я имею до сих пор, которое не работает, но иллюстрирует линии, о которых я думаю:
TotalDf <- function(x){
tmpNumberOfTypes <- c(levels(x$Type))
for( i in tmpNumberOfTypes){
subSetofData <- subset(x, Type = i, select = Value)
if( i == 1) {
totalDf <- subSetOfData }
else{
totalDf <- cbind(totalDf, subSetofData)}
}
return(totalDf)
}
Заранее спасибо за любые мысли или идеи по этому поводу,
С уважением,
EDIT:
Благодаря комментарию Йориса (см. Ниже) я получил правильное направление, однако, пытаясь перевести его решение на мой фрейм данных, я столкнулся с дополнительными проблемами. Предложенный им ответ работает и дает мне следующую (правильную) сумму значений A и B:
> tmp78 <- tapply(DF$value,DF$id,sum)
> tmp78
1 2 3 4 5 6
6 8 10 12 9 10
> data.frame(tmp78)
tmp78
1 6
2 8
3 10
4 12
5 9
6 10
Однако, когда я пробую это решение на моем фрейме данных, оно не работает:
> subSetOfData <- copyOfTradesList[c(1:3,11:13),c(1,10)]
> subSetOfData
Instrument AccountValue
1 JPM 6997
2 JPM 7261
3 JPM 7545
11 KFT 6992
12 KFT 6944
13 KFT 7069
> unlist(sapply(rle(subSetOfData$Instrument)$lengths,function(x) 1:x))
Error in rle(subSetOfData$Instrument) : 'x' must be an atomic vector
> subSetOfData$InstrumentNumeric <- as.numeric(subSetOfData$Instrument)
> unlist(sapply(rle(subSetOfData$InstrumentNumeric)$lengths,function(x) 1:x))
[,1] [,2]
[1,] 1 1
[2,] 2 2
[3,] 3 3
> subSetOfData$id <- unlist(sapply(rle(subSetOfData$InstrumentNumeric)$lengths,function(x) 1:x))
Error in `$<-.data.frame`(`*tmp*`, "id", value = c(1L, 2L, 3L, 1L, 2L, :
replacement has 3 rows, data has 6
У меня тревожная идея, что я хожу по кругу ...