У меня есть фрейм данных в R, который я хочу агрегировать.Сводная функция, которую я хочу применить к каждому подмножеству, является пользовательской функцией, которая принимает несколько переменных (столбцов) в качестве входных данных и возвращает вектор или список переменной длины .В качестве выходных данных я хотел бы иметь фрейм данных со столбцом переменной группировки и еще один столбец, содержащий выходной вектор (различной длины).
Чтобы привести пример, предположим, у меня естьследующий кадр данных:
df <- data.frame( particle = c(rep("X",5),rep("Y",3),rep("Z",4)),
time = c(1:5,1:3,1:4), state = c(c("A","A","B","C","A"),c("A","B","B"),
c("B","C","A","A")), energy = round(runif(12,0,10)))
> df
particle time state energy
1 X 1 A 9
2 X 2 A 8
3 X 3 B 7
4 X 4 C 5
5 X 5 A 0
6 Y 1 A 1
7 Y 2 B 7
8 Y 3 B 7
9 Z 1 B 3
10 Z 2 C 9
11 Z 3 A 5
12 Z 4 A 6
Я хотел бы получить для каждой частицы список энергии, которой они обладали каждый раз, когда они меняли состояние.Вывод, который я ищу, выглядит примерно так:
>
particle energy
1 X c(9,7,5,0)
2 Y c(1,7)
3 Z c(3,9,5)
Для этого я бы определил функцию, подобную следующей:
myfun <- function(state, energy){
tempstate <- state[1]
energyvec <- energy[1]
for(i in 2:length(state)){
if(state[i] != tempstate){
energyvec <- c(energyvec, energy[i])
tempstate <- state[i]
}
}
return(energyvec)
}
И попытался бы передать ее в агрегаткаким-то образом
Две структуры данных, которые я пробовал для этого, являются data.frame и data.table.
В data.frame использование пользовательской функции, которая возвращает вектор, похоже, дает правильный формат выводаЯ ищу, где выходной столбец на самом деле является списком, и каждая строка содержит список с выводом функции.Тем не менее, я не могу передать несколько столбцов функции при агрегировании таким образом.
С таблицей data.table агрегацию легче выполнять, рассматривая функцию нескольких переменных.Тем не менее, я не могу получить результат, который я ищу.Действительно,
dt <- data.table(df)
dt[,myfun(state, energy), by= Particle]
возвращает только первый элемент energyvec (вместо вектора), а
dt <- data.table(df)
dt[,as.list(myfun(state, energy)), by= Particle]
не работает, так как выходы не имеют одинаковую длину.
Есть ли альтернативный способ сделать это?
Заранее большое спасибо за вашу помощь!