我的R中的向量包含很多0和一些非零数字。每个向量都以非零数字开头。
例如< 1,0,0,0,0,0,2,0,0,0,0,0,4,0,0,0>
我想将所有零设置为等于最近的非零数字。
即。该矢量将变为< 1,1,1,1,1,1,2,2,2,2,2,2,4,4,4,4>
我需要为大约100个向量执行此操作,每个向量包含大约600万个条目。目前我正在使用for循环:
for(k in 1:length(vector){
if(vector[k] == 0){
vector[k] <- vector[k-1]
}
}
有更有效的方法吗?
谢谢!
答案 0 :(得分:7)
一种选择是将0
替换为NA
,然后使用zoo::na.locf
:
x <- c(1,0,0,0,0,0,2,0,0,0,0,0,4,0,0,0)
x[x == 0] <- NA
zoo::na.locf(x) ## you possibly need: `install.packages("zoo")`
# [1] 1 1 1 1 1 1 2 2 2 2 2 2 4 4 4 4
感谢Richard向我展示了如何使用replace
,
zoo::na.locf(replace(x, x == 0, NA))
答案 1 :(得分:4)
你可以试试这个:
k <- c(1,0,0,0,0,0,2,0,0,0,0,0,4,0,0,0)
k[which(k != 0)[cumsum(k != 0)]]
或cummax
不合适的其他案例
k <- c(1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0)
k[which(k != 0)[cumsum(k != 0)]]
逻辑:
我保持&#34;追踪&#34;对于非零which(k != 0)
的向量元素的索引,我们将此新向量表示为x
,x=c(1, 7, 13)
接下来我要去&#34;示例&#34;这个新的载体。怎么样?从k
我创建了一个新的向量,每当有一个非零元素cumsum(k != 0)
时递增,我们将这个新向量表示为y
y=c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3)
我是&#34;采样&#34;来自向量x
:x[y]
,即将x
的第一个元素取出6次,然后将第二个元素取出6次,将第三个元素取出3次。我们将此新向量表示为z
,z=c(1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 13, 13, 13)
我是&#34;采样&#34;来自向量k
,k[z]
,即我将第一个元素取出6次,然后是第7个元素6次,然后是第13个元素3次。
答案 2 :(得分:1)
加入@李哲源&#39答案:
如果需要用最近的非NA值替换前导NA,并用最后一个非NA值替换其他NA,则代码可以是:
x <- c(0,0,1,0,0,0,0,0,2,0,0,0,0,0,4,0,0,0)
zoo::na.locf(zoo::na.locf(replace(x, x == 0, NA),na.rm=FALSE),fromLast=TRUE)
# you possibly need: `install.packages("zoo")`
# [1] 1 1 1 1 1 1 1 1 2 2 2 2 2 2 4 4 4 4