Используя data.table, возможно ли создать новый столбец, повторяя первые значения X в группе - PullRequest
2 голосов
/ 16 апреля 2020

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

Некоторые сгенерированные данные:

library(data.table)

set.seed(123)  
my.df <- data.table(
    ID = rep(letters[1:2], each = 6),
    factor1 = rep(letters[9:11], each = 2), 
    col1 = sample(1:30, 12, replace = TRUE))

# ID factor1 col1
# 1:  a       i    8
# 2:  a       i    9
# 3:  a       j   15
# 4:  a       j   26
# 5:  a       k   13
# 6:  a       k    2
# 7:  b       i    7
# 8:  b       i    9
# 9:  b       j    7
# 10:  b       j    4
# 11:  b       k   29
# 12:  b       k   23

Моя проблема: я хотел бы создать новый столбец col2 с первыми двумя строками данных в col1, где factor1 == i, и повторить числа до тех пор, пока ID == a, а затем то же самое для ID == b. Буду признателен за любую помощь, предпочтительнее решения data.table

Новый col2 должен выглядеть следующим образом:

set.seed(123)  
my.df2 <- data.table(
    ID = rep(letters[1:2], each = 6),
    factor1 = rep(letters[9:11], each = 2), 
    col1 = sample(1:30, 12, replace = TRUE),
    col2 = c(12,13,12,13,12,13,4,10,4,10,4,10))

# ID factor1 col1 col2
# 1:  a       i   23   15
# 2:  a       i   21   19
# 3:  a       j   14   15
# 4:  a       j   17   19
# 5:  a       k   17   15
# 6:  a       k   13   19
# 7:  b       i    8   22
# 8:  b       i    1   11
# 9:  b       j   19   22
# 10:  b       j   14   11
# 11:  b       k   19   22
# 12:  b       k   20   11

Это было решено с помощью приведенного ниже кода комментария:

my.df[, col2 := rep(head(col1[factor1 == 'i'], 2), length.out = .N), ID]

Другое решение, так как у меня всегда одинаковое количество групп в factor1:

my.df[, col2 := rep(head(col1[factor1 == 'i'], 2), times = 3), ID]

Поскольку у меня есть 2 фактора для группировки, я не показал в этом примере, я изменил окончание:

my.df[, col2 := rep(head(col1[factor1 == 'i'], 2), times = 3), by=list(ID1, ID2)]

1 Ответ

3 голосов
/ 16 апреля 2020

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

library(data.table)
my.df[, col2 := rep(col1[factor1 == 'i'], length.out = .N), ID]

Если в конкретном ID, где factor1 == 'i' более 2 значений, но вас интересуют только первые 2, мы можем использовать head.

my.df[, col2 := rep(head(col1[factor1 == 'i'], 2), length.out = .N), ID]


my.df
#    ID factor1 col1 col2
# 1:  a       i   15   15
# 2:  a       i   19   19
# 3:  a       j   14   15
# 4:  a       j    3   19
# 5:  a       k   10   15
# 6:  a       k   18   19
# 7:  b       i   22   22
# 8:  b       i   11   11
# 9:  b       j    5   22
#10:  b       j   20   11
#11:  b       k   14   22
#12:  b       k   22   11

данные

set.seed(123)
my.df <- data.table(
        ID = rep(letters[1:2], each = 6),
        factor1 = rep(letters[9:11], each = 2), 
        col1 = sample(1:30, 12, replace = TRUE))
...