Подмножество и повторение строк в кадре данных с использованием R - PullRequest
0 голосов
/ 11 сентября 2018

Предположим, у нас есть следующие данные с именами столбцов "id", "time" и "x":

df<-
structure(
list(
id = c(1L, 1L, 1L, 2L, 2L, 3L, 3L),
time = c(20L, 6L, 7L, 11L, 13L, 2L, 6L),
x = c(1L, 1L, 0L, 1L, 1L, 1L, 0L)
),
.Names = c("id", "time", "x"),
class = "data.frame",
row.names = c(NA,-7L)
)

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

library(dplyr) 
df<-df%>% 
group_by(id) %>% 
filter( ((x)==0 & row_number()==n())| ((x)==1 & row_number()==n()))

Что остается нерешенным, так это аспект повторения. Ожидаемый результат будет выглядеть как

df <-
structure(
list(
id = c(1L, 1L, 1L, 2L, 2L, 3L, 3L),
time = c(7L, 7L, 7L, 13L, 13L, 6L, 6L),
x = c(0L, 0L, 0L, 1L, 1L, 0L, 0L)
),
.Names = c("id", "time", "x"),
class = "data.frame",
row.names = c(NA,-7L)
)

Спасибо за вашу помощь заранее.

Ответы [ 4 ]

0 голосов
/ 11 сентября 2018

Используя data.table вы можете попробовать

library(data.table)
setDT(df)[,.(time=rep(time[.N],.N), x=rep(x[.N],.N)), by=id]
   id time  x
1:  1    7  0
2:  1    7  0
3:  1    7  0
4:  2   13  1
5:  2   13  1
6:  3    6  0
7:  3    6  0

После @thelatemai, чтобы избежать имен столбцов, вы также можете попробовать

df[, .SD[rep(.N,.N)], by=id]
   id time x
1:  1    7 0
2:  1    7 0
3:  1    7 0
4:  2   13 1
5:  2   13 1
6:  3    6 0
7:  3    6 0
0 голосов
/ 11 сентября 2018

Мы можем использовать ave, чтобы найти max номер строки для каждого ID и поднаборить его из фрейма данных.

df[ave(1:nrow(df), df$id, FUN = max), ]

#    id time x
#3    1    7 0
#3.1  1    7 0
#3.2  1    7 0
#5    2   13 1
#5.1  2   13 1
#7    3    6 0
#7.1  3    6 0
0 голосов
/ 11 сентября 2018

slice будет вашим другом в тидиверсе, на мой взгляд:

df %>%
  group_by(id) %>%
  slice(rep(n(),n()))
## A tibble: 7 x 3
## Groups:   id [3]
#     id  time     x
#  <int> <int> <int>
#1     1     7     0
#2     1     7     0
#3     1     7     0
#4     2    13     1
#5     2    13     1
#6     3     6     0
#7     3     6     0

В data.table вы также можете использовать аргумент mult= объединения:

library(data.table)
setDT(df)
df[df[,.(id)], on="id", mult="last"]
#   id time x
#1:  1    7 0
#2:  1    7 0
#3:  1    7 0
#4:  2   13 1
#5:  2   13 1
#6:  3    6 0
#7:  3    6 0

И в базе R, merge доставит вас туда тоже:

merge(df["id"], df[!duplicated(df$id, fromLast=TRUE),])
#  id time x
#1  1    7 0
#2  1    7 0
#3  1    7 0
#4  2   13 1
#5  2   13 1
#6  3    6 0
#7  3    6 0
0 голосов
/ 11 сентября 2018

Вы можете сделать это, используя last(), чтобы получить последнюю строку внутри каждого идентификатора.

df %>%
    group_by(id) %>%
    mutate(time = last(time),
           x = last(x))

Поскольку last(x) возвращает одно значение, оно расширяется, чтобы заполнить все строки вmutate() звонок.

Это также может быть применено к произвольному числу переменных с использованием mutate_at:

df %>%
    group_by(id) %>%
    mutate_at(vars(-id), ~ last(.))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...