我正在努力让我的数据准备好以后进行序列分析;要做到这一点,我需要在值1和2之间插入值1。 因此,对于每一行,1和2之间的所有NA都等于1。我在下面列出了一个示例表;在我的实际数据中,每一行都是一个独特的个体,每列都是一个时间段。 1代表录取,2代表节目放电。我试图将“录取”和“放电”之间的时间段设置为等于1表示已注册该程序,然后将剩余的NA设置为0表示不在程序中。每行/每个人可以有多个录取。
我一直在尝试使用apply,我可以自己更改值,但是我不能在值1和2之间替换NA。任何指导都会非常感激!
mdat <- matrix(c(1,NA,NA,NA,2,NA,NA,1,NA,2, NA,NA,1,2,NA,NA,NA,1,NA,2), nrow = 2, ncol=10, byrow=TRUE,
dimnames = list(c("row1", "row2"), c("C.1", "C.2", "C.3", "C.4", "C.5", "C.6", "C.7", "C.8", "C.9", "C.10")))
| | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8| c9 | c10 | ---------------------------------------------------------- |row 1 | 1 | NA | NA | NA | 2 | NA | NA | 1 | NA | 2 | |row 2 | NA | NA | 1 | 2 | NA | NA | NA | 1 | NA | 2 |
期望的结果;
| | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8| c9 | c10 | ---------------------------------------------------------- |row 1 | 1 | 1 | 1 | 1 | 2 | NA | NA | 1 | 1 | 2 | |row 2 | NA | NA | 1 | 2 | NA | NA | NA | 1 | 1 | 2 |
答案 0 :(得分:4)
如果我正确理解了您的需求,您可以先将NA
替换为0
,然后按周期搜索2的比较结果,以填充&#34;间隙&#34;使用1
(然后转换结果以保留以前的格式):
mdat[is.na(mdat)] <- 0
mdat <- t(apply(mdat, 1, function(x) {x[cumsum(x==2) < cumsum(x==1)] <- 1; x}))
mdat
# C.1 C.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9 C.10
#row1 1 1 1 1 2 0 0 1 1 2
#row2 0 0 1 2 0 0 0 1 1 2
答案 1 :(得分:2)
1)我们可以通过使用zoo包中的na.locf
来填充NA,然后替换对应于1的mdat
元素,从而得到一个相对紧凑的解决方案。填写版本1:
library(zoo)
replace(mdat, t(na.locf(t(mdat))) == 1, 1)
,并提供:
C.1 C.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9 C.10
row1 1 1 1 1 2 NA NA 1 1 2
row2 NA NA 1 2 NA NA NA 1 1 2
2)或者使用na.locf
并将mdat
中NA为NA的传播的2替换为NA。我们使用dplyr管道(尽管如果需要可以将其删除):
library(dplyr)
library(zoo)
mdat %>% t %>% na.locf %>% t %>% replace(. == 2 & is.na(mdat), NA)
答案 2 :(得分:0)
NA
1
之后立即替换所有1
。我的帖子只是为了让有空闲时间和microbenchmark
副本的人都可以看到na.locf
做得多好。
foo <- c(1,NA,2,NA,1,2,1,NA,NA,NA,2,NA,NA)
foo
length(foo)
for(jj in 2:length(foo) ) {
if ( (!is.na(foo[jj-1]) && foo[jj-1]==1) & is.na(foo[jj])) foo[jj]=1
}
foo
#then replace remaining `NA` with zero if desired