r - 对于非零之前的值,用 NA 替换零
问题描述
我是 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
需要返回修改后的向量。否则,返回值会出乎意料(在这种情况下,赋值将返回一个s NA
,而 slapply
将返回一行NA
s 的数据框,而不是您想要的数据框)。
第三,您需要注意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.
推荐阅读
- c++ - 如何使用模板实现在 C++ 中安全地将任何较大类型转换为较小类型的函数?
- laravel - 在 Laravel 中注册后如何立即登录?
- express - 在 jest 被拆除后,由于导入导致不止一项测试失败 - Supertest Typescript 和 Express API
- apache-flink - flink 删除指标组
- ios - 是否可以创建 UITextfield 扩展,然后将其作为函数调用?谢谢你
- mule4 - 如何在 Mule 4 中创建数据库配置作为库?
- python - 没有找到用于解析的正确标签
- sas - 按降序 QuestionPercentage 变量排序
- typescript - NestJS 和 Mongoose 通过引用对象 Id 查找
- api - 为什么我的使用 Entity Framework 6 的 Web Api PUT 不断写入新的重复记录而不是更新它们?