Как назначить новое значение для первых n строк в подмножестве, используя data.table? - PullRequest
0 голосов
/ 23 апреля 2019

Я пытаюсь установить подмножество моей таблицы данных, выбрать n верхних строк и присвоить им новое значение.

Моя первая попытка была следующей:

DT[condition_1 & condition_2][1:N][x := 1]

Однако данные не могутПохоже, что вы не можете назначать конвейерные назначения подобным образом, и при этом вы не можете выбирать верхние строки (с учетом нескольких условий) без конвейера.

Моя вторая попытка была следующей:

DT[intersect(which(condition_1 & condition_2), c(1:N)), x := 1]

Эторешает некоторые из проблем, но работает, только если условия выполняются в верхних N строках таблицы, а не в первые N раз, когда условия выполняются.

RE: Markus

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

1, ранг <80, автоматически включается; </p>

2, ранг от 80 до 120 и член предыдущего года, включены;

3, оставшиеся места, заполненные рангом, пока количество участников не достигнет 100 в год.

Ниже приведена фиктивная версиямой код с вопросом лЭто было закомментировано и уменьшенный пример:

Example <- data.table("stock_id" = rep(LETTERS[1:20],20), "year" = rep(1999:2018,each=20),"zscore" = rnorm(400))
Example[,Rank:=rank(zscore),by=year]

Example[,membership := 0]
Example[year==min(year) & Rank <= 10, membership := 1]
Example[Rank<=5,membership := 1]
Example[,p_membership := shift(membership,n=1)]
setkey(Example,year,Rank)

n <- data.table(unique(Example[,year]))
n <- n[!(V1 == min(year))]

for (i in n[,V1]){
  Example[year == i & between(Rank, 6, 15) & p_membership == 1, membership := 1]
  N <- abs(10 - sum(Example[year == i, membership], na.rm=TRUE))
  #  Attempt 1 ---->     Example[year == i & membership ==0][1:N][membership := 1]
  #  Attempt 2 ---->     Example[intersect(which(year == i & membership ==0), c(1:N)), membership := 1]
    Example[,p_membership := shift(membership,n=1), by=gvkey]
}

Решение для stock_id "A" выглядит примерно так:

   stock_id year       zscore Rank membership p_membership
 1:        A 1999 -0.275206888   10          0           NA
 2:        A 2000  0.419941872   16          0            0
 3:        A 2001  0.002890563    9          0            0
 4:        A 2002 -1.464640431    2          1            0
 5:        A 2003 -1.701047022    1          1            1
 6:        A 2004 -0.252197958    4          1            1
 7:        A 2005  0.234173727   10          1            1
 8:        A 2006 -0.024872099   19          0            1
 9:        A 2007 -0.188246291   20          0            0
10:        A 2008 -0.267944869    6          1            0
11:        A 2009  0.728570748   12          1            1
12:        A 2010 -0.040244792   11          1            1
13:        A 2011  0.942448885   18          0            1
14:        A 2012 -0.051872395   11          0            0
15:        A 2013 -1.171291738    4          1            0
16:        A 2014  1.505583171   18          0            1
17:        A 2015  0.507555473   15          0            0
18:        A 2016 -0.310156393    9          1            0
19:        A 2017  0.713142517   14          1            1
20:        A 2018  2.196859750   20          0            1

Само собой разумеется, любая помощь будет высоко оценена.

...