Подмножество последней строки из каждой группы идентификаторов в длинном наборе данных в R - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть набор продольных данных из 142 415 строк и 965 столбцов. Для каждого идентификатора в наборе данных имеется несколько строк, причем необязательно одинаковое количество строк для каждого идентификатора.

Я хотел бы получить последнюю строку (данные уже отсортированы) для каждого идентификатора и создать фрейм данных только из них, сохраняя все оставшиеся 964 столбца данных.

Когда я смотрю на предыдущие вопросы, касающиеся этого, во многих предложениях используется aggregate(), и я не могу использовать это (по крайней мере из того, что я знаю), потому что у меня слишком много столбцов.

Я попробовал следующее, но это вызвало сбой в работе моего компьютера, поэтому мне интересно, есть ли более быстрый способ сделать это, чем создать список и затем сформировать из него фрейм данных:

data.list<-by(data.in, data.in$ID, tail, n=1)
data.new<-do.call("rbind", as.list(data.list))

Ответы [ 3 ]

2 голосов
/ 06 ноября 2019

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

library(dplyr) 

iris %>% 
group_by(Species) %>%
slice(n())

# Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#         <dbl>       <dbl>        <dbl>       <dbl> <fct>     
#1          5           3.3          1.4         0.2 setosa    
#2          5.7         2.8          4.1         1.3 versicolor
#3          5.9         3            5.1         1.8 virginica 

Или вы можете использовать data.table

library(data.table)
setDT(iris)[, .SD[.N], by=Species]
0 голосов
/ 06 ноября 2019

Мы также можем использовать filter

library(dplyr)
iris %>%
    group_by(Species) %>%
    filter(row_number()== n())
0 голосов
/ 06 ноября 2019

Ответ выше, вероятно, работает лучше, так как ваши данные упорядочены. Этот метод также работает, если данные не упорядочены.

Я предполагаю, что есть один столбец, который вы хотите использовать для выбора строки (например, даты).

Вы можете решить это с помощьюиндексировать большой набор данных, а затем выбрать строку идентификатора и даты вместе с индексом, а затем использовать суммирование, чтобы найти правильный индекс и отфильтровать больший набор данных. Таким образом, вам не придется качаться вокруг всех этих сотен колонн.

library(tidyverse)
#Random dataset, date is coded as numeric for practical purposes. 
#var1 and var2 pose as the >900 columns you have
large_dataset <- tibble(id=c(1,1,1,2,2,2,2,3,3,4),
                        date=c(10,15,20,10,15,20,25,10,15,10),
                        var1=rpois(10,50),
                        var2=rpois(10,30))

large_dataset

# A tibble: 10 x 4
  id  date  var1  var2
   <dbl> <dbl> <int> <int>
 1     1    10    41    39
 2     1    15    56    32
 3     1    20    41    34
 4     2    10    46    35
 5     2    15    44    38
 6     2    20    50    33
 7     2    25    58    34
 8     3    10    44    28
 9     3    15    49    37
10     4    10    62    38


large_dataset <- mutate(large_dataset,index = c(1:nrow(large_dataset)))

key <- select(large_dataset,id,date,index) 

key <- group_by(key,id) %>%
summarise(date=max(date)) %>%
left_join(key,by=c("id","date"))

small_dataset <- filter(large_dataset,index %in% key$index) %>% 
select(-index) #Removing the index variable since it has served its purpose


id  date  var1  var2
<dbl> <dbl> <int> <int>

1     1    20    41    34
2     2    25    58    34
3     3    15    49    37
4     4    10    62    38
...