r - 用NA替换零以表示非零之前的值

标签 r

我是R的新手,并且一直在努力解决以下问题,所以我希望有人能够为我提供帮助。

样本数据代表股票价格返回(每行是一个月周期)。实际数据集要大得多,其结构类似于以下输入:

输入:

stock1 <- c(0.01, -0.02, 0.01, 0.05, 0.04, -0.02)
stock2 <- c(0, 0, 0.02, 0.04, -0.03, 0.02)
stock3 <- c(0, 0, 0.02, 0, -0.01, 0.03)
stock4 <- c(0, -0.02, 0.01, 0, 0, -0.02)
df <- cbind(stock1,stock2,stock3,stock4)

     stock1 stock2 stock3 stock4
[1,]   0.01   0.00   0.00   0.00
[2,]  -0.02   0.00   0.00  -0.02
[3,]   0.01   0.02   0.02   0.01
[4,]   0.05   0.04   0.00   0.00
[5,]   0.04  -0.03  -0.01   0.00
[6,]  -0.02   0.02   0.03  -0.02

对于给定的股票,在非零之前的任何零都表示缺少数据,而不是在此期间返回零。我想将这些值设置为NA,所以我要实现的输出如下:

所需的输出:
stock1 <- c(0.01, -0.02, 0.01, 0.05, 0.04, -0.02)
stock2 <- c(NA, NA, 0.02, 0.04, -0.03, 0.02)
stock3 <- c(NA, NA, 0.02, 0, -0.01, 0.03)
stock4 <- c(NA, -0.02, 0.01, 0, 0, -0.02)
df <- cbind(stock1,stock2,stock3,stock4)

     stock1 stock2 stock3 stock4
[1,]   0.01     NA     NA     NA
[2,]  -0.02     NA     NA  -0.02
[3,]   0.01   0.02   0.02   0.01
[4,]   0.05   0.04   0.00   0.00
[5,]   0.04  -0.03  -0.01   0.00
[6,]  -0.02   0.02   0.03  -0.02

我已经尝试了一些方法,但是它们似乎只适用于单个向量,而不是具有多列的数据集。我尝试使用lapply来解决此问题,但到目前为止还没有任何运气。我得到的最接近的信息如下所示。

我的单向量解决方案:
stock1[1:min(which(stock1!=0))-1 <- NA

我的多向量解决方案不起作用:
lapply(df,function(x) x[1:min(which(x!=0))-1 <- NA]

将不胜感激任何指导!谢谢!

最佳答案

有三个问题。首先,写:

df <- cbind(stock1,stock2,stock3,stock4)

不创建数据框。它创建一个矩阵。当您尝试使用lapply时,这是一个问题,它将在数据框的列上但在矩阵的元素上运行。相反,您应该写:
df <- data.frame(stock1,stock2,stock3,stock4)

其次,您在lapply中使用的函数需要返回修改后的向量。否则,返回值将是意外的(在这种情况下,赋值将返回单个NA,并且lapply将返回一行NA的数据帧,而不是所需的数据帧)。

第三,当1:n可以为零时(即,当第一个股票报价不为零时),您需要小心n,因为1:0给出了c(1,0)序列而不是空序列。 (可以说这是R最愚蠢的功能之一。)

因此,以下内容将为您提供所需的信息:
stock1 <- c(0.01, -0.02, 0.01, 0.05, 0.04, -0.02)
stock2 <- c(0, 0, 0.02, 0.04, -0.03, 0.02)
stock3 <- c(0, 0, 0.02, 0, -0.01, 0.03)
stock4 <- c(0, -0.02, 0.01, 0, 0, -0.02)
df <- data.frame(stock1,stock2,stock3,stock4)

as.data.frame(lapply(df, function(x) {
    n <- min(which(x != 0)) - 1
    if (n > 0)
        x[1:n] <- NA
    x
}))

输出是预期的:
  stock1 stock2 stock3 stock4
1   0.01     NA     NA     NA
2  -0.02     NA     NA  -0.02
3   0.01   0.02   0.02   0.01
4   0.05   0.04   0.00   0.00
5   0.04  -0.03  -0.01   0.00
6  -0.02   0.02   0.03  -0.02

更新:如@Daniel_Fischer所述,有一个巧妙的技巧可以避免1:0问题。您可以改写:
as.data.frame(lapply(df, function(x) {
    n <- min(which(x != 0)) - 1
    x[0:n] <- NA    # use 0:n instead of 1:n
    x
}))

这利用了以下事实:R在这种类型的索引操作中会忽略零,因此:
x[0:0] <- NA    # same as x[0] <- NA and does nothing
x[0:1] <- NA    # same as x[1] <- NA
x[0:2] <- NA    # same as x[1:2] <- NA, etc.

关于r - 用NA替换零以表示非零之前的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51834220/

相关文章:

r - 在 R 中嵌套 ifelse

r - .data 和 cur_data() 之间的区别

r - 两个几乎相同的向量之间的角度

r - 评估包含另一个调用的调用(调用中的调用)

r - 只显示正在使用的标签?

r - 在 R 中的复制函数中使用大括号

r - 如何按 R 中的自定义规则对字符串列表进行排序?

r - 两个数据集之间均值差异的置信区间

r - 绑定(bind)具有不同数据类型的行

r - 从索引向量创建二元邻接矩阵