我的data.table看起来像这样:
+------------+--------+
| Date | CC RR |
+------------+--------+
| 31.01.1985 | C1 0.1|
| 28.02.1985 | C1 0.8|
| 29.03.1985 | C1 0.9|
| 30.04.1985 | C1 2 |
| 31.05.1985 | C1 0 |
| 28.06.1985 | C1 0 |
| 31.01.1985 | C2 NA |
| 28.02.1985 | C2 0 |
| 29.03.1985 | C2 0.1|
| 30.04.1985 | C2 0 |
| 31.05.1985 | C2 0.4|
| 28.06.1985 | C2 0 |
CC
(“公司代码”列)列具有用于标识公司的唯一公司代码,Date
列具有日期,而RR
列具有股票收益。我的实际数据集有超过2000家公司,为期30年。
我的问题如下:对于每个公司,我想将每个公司最后一行中RR
的值从零转换为NA。具体来说,我想将以下行的RR
的值从0更改为NA:
31.05.1985 | c1
28.06.1985 | c1
28.06.1985 | c2
我不想更改中间日期,例如28.02.1985 | c2
或30.04.1985 c2
,并且我希望保留现有的NA,例如31.01.1985 | C2
。
我尝试使用
length(Data[, CC])-match(unique(Data[,CC]),rev(Test3[,CC]))+1
以获得各自公司代码最后一次出现的索引列表,然后迭代直到RR列中的第一个非零值,但是我不知道如何将其应用于r。中的data.table。
我当然可以转换所有零,但这不能解决我的问题:
Date[RR==0, "RR"] <- NA
有人可以帮我吗?我将不胜感激任何帮助。此致。
答案 0 :(得分:3)
首先,请发布实际可用数据,而不要发布ascii艺术。我迅速将您发布的内容编辑到一个用空格分隔的文件中,并阅读:
R> dt <- fread("/tmp/data.txt")
R> dt
Date CC RR
1: 31.01.1985 C1 0.1
2: 28.02.1985 C1 0.8
3: 29.03.1985 C1 0.9
4: 30.04.1985 C1 2.0
5: 31.05.1985 C1 0.0
6: 28.06.1985 C1 0.0
7: 31.01.1985 C2 NA
8: 28.02.1985 C2 0.0
9: 29.03.1985 C2 0.1
10: 30.04.1985 C2 0.0
11: 31.05.1985 C2 0.4
12: 28.06.1985 C2 0.0
R> dput(dt)
structure(list(Date = c("31.01.1985", "28.02.1985", "29.03.1985",
"30.04.1985", "31.05.1985", "28.06.1985", "31.01.1985", "28.02.1985",
"29.03.1985", "30.04.1985", "31.05.1985", "28.06.1985"), CC = c("C1",
"C1", "C1", "C1", "C1", "C1", "C2", "C2", "C2", "C2", "C2", "C2"
), RR = c(0.1, 0.8, 0.9, 2, 0, 0, NA, 0, 0.1, 0, 0.4, 0)), row.names = c(NA,
-12L), class = c("data.table", "data.frame"),
.internal.selfref = <pointer: 0x5601c8da9cd0>)
R>
dput()
的输出可以由R评估并重新创建数据结构。
接下来,您的数据分析。首先,您想按小组工作! data.table的强项之一是分组。其次,您可能想要类似“零时的最大订单索引”之类的东西。以下应该起作用:
R> dt[, rle:=rleid(RR), by="CC"]
R> dt
Date CC RR rle
1: 31.01.1985 C1 0.1 1
2: 28.02.1985 C1 0.8 2
3: 29.03.1985 C1 0.9 3
4: 30.04.1985 C1 2.0 4
5: 31.05.1985 C1 0.0 5
6: 28.06.1985 C1 0.0 5
7: 31.01.1985 C2 NA 1
8: 28.02.1985 C2 0.0 2
9: 29.03.1985 C2 0.1 3
10: 30.04.1985 C2 0.0 4
11: 31.05.1985 C2 0.4 5
12: 28.06.1985 C2 0.0 6
R>
我们使用data.table中非常有用的rleid()
函数来获取rle()
重复的 index 值。现在,我们“只是”需要再次分组,如果rle
的值等于max(rle)
的值,我们便有了所需的位置并将其设置为NA
。
R> dt[, ind:=which.max(rle), by=CC] # find max index
R> dt[ ind==rle & RR==0.0, RR:=NA_real_, by=CC ] # at max ind AND zero set NA
R> dt[, ind:=NULL ] # remove index helper
R> dt
Date CC RR rle
1: 31.01.1985 C1 0.1 1
2: 28.02.1985 C1 0.8 2
3: 29.03.1985 C1 0.9 3
4: 30.04.1985 C1 2.0 4
5: 31.05.1985 C1 NA 5
6: 28.06.1985 C1 NA 5
7: 31.01.1985 C2 NA 1
8: 28.02.1985 C2 0.0 2
9: 29.03.1985 C2 0.1 3
10: 30.04.1985 C2 0.0 4
11: 31.05.1985 C2 0.4 5
12: 28.06.1985 C2 NA 6
R>
仅使用代码:
dt <- fread("/tmp/data.txt")
dt[, rle:=rleid(RR), by=CC]
dt[, ind:=which.max(rle), by=CC]
dt[ ind==rle & RR==0.0, RR:=NA_real_, by=CC ]
dt[, ind:=NULL ]
dt
答案 1 :(得分:2)
使用data.table
的一种方法:
将日期从旧到新排序,然后创建累积总和rr
。然后,所有行的总和为0,我们将rr
更改为NA
。请注意,由于cumsum
没有一个na.rm
arg,因此有几个额外的步骤。
# create example data
df <- data.frame(
date = rep(seq(as.Date("1985-01-31"), by="day", length.out=6), 2),
cc = rep(c("c1", "c2"), each=6),
rr = c(0.1, 0.8, 0.9, 2, 0, 0, NA, 0, 0.1, 0, 0.4, 0),
stringsAsFactors = FALSE
)
# change to data.table
library(data.table)
setDT(df)
# sort date old to new
df <- df[order(cc, -date)]
# save a copy of the rr col
df[ , rr_orig := rr]
# turn NAs into 0s because no "na.rm" arg in cumsum
df[is.na(rr), rr := 0]
# create cumsum
df[ , cumrr := cumsum(rr), by=cc]
# replace 0s with NAs in rr, wherever cumsum is 0
df[cumrr == 0, rr := NA]
# put the NAs back into rr from rr_orig
df[is.na(rr_orig), rr := NA]
# clean up by deleting rr_orig and cumrr cols, and re-sort date
df[ , c("rr_orig", "cumrr") := NULL]
df <- df[order(cc, date)]
结果
> df
date cc rr
1: 1985-01-31 c1 0.1
2: 1985-02-01 c1 0.8
3: 1985-02-02 c1 0.9
4: 1985-02-03 c1 2.0
5: 1985-02-04 c1 NA
6: 1985-02-05 c1 NA
7: 1985-01-31 c2 NA
8: 1985-02-01 c2 0.0
9: 1985-02-02 c2 0.1
10: 1985-02-03 c2 0.0
11: 1985-02-04 c2 0.4
12: 1985-02-05 c2 NA