在R中:如何替换两个整数之间的向量中的NA

Ant*_*ien 5 r vector

我有以下向量:

A:(NA NA NA NA 1 NA NA 4 NA NA 1 NA NA NA NA NA 4 NA 1 NA 4)
Run Code Online (Sandbox Code Playgroud)

我想将1到4之间的所有Nas替换为2(而不是4到1之间的Nas)

您有什么建议/建议用于此任务的方法吗?

也可以将其作为数据框进行管理:

 A 
----
 NA 
 NA 
 NA 
 NA 
 1 
 NA 
 NA 
 4 
 NA 
 NA 
 1 
 NA 
 NA 
 NA 
 NA 
 NA
 4 
 NA 
 1
 NA 
 4
----
Run Code Online (Sandbox Code Playgroud)

编辑:1.我将字符串“ Na”更改为NA。

解决方案/更新 谢谢大家的见解。我从他们那里学到了针对我的案例的以下解决方案。我希望它对其他人有用:

A <- c(df$A)

index.1<-which(df$A %in% c(1)) # define location for 1s in A
index.14<-which(df$A %in% c(1,4)) # define location for 1s and 4s in A

loc.1<-which(index.14 %in% index.1) # location of 1s in  index.14
loc.4<-loc.1+1 # location of 4s relative to 1s in index.14

start.i<-((index.14[loc.1])+1) # starting index for replacing with 2
end.i<-((index.14[loc.4])-1) # ending index for replacing with 2 in index

fill.v<-sort(c(start.i, end.i))# sequence of indexes to fill-in with # 2

# create matrix of beginning and ending sequence
fill.m<-matrix(fill.v,nrow = (length(fill.v)/2),ncol = 2, byrow=TRUE) 

# create a list with indexes to replace
list.1<-apply(fill.m, MARGIN=1,FUN=function(x) seq(x[1],x[2])) 

# unlist list to use as the indexes for replacement
list.2<-unlist(list.1) 

df$A[list.2] <- 2 # replace indexed location with 2
Run Code Online (Sandbox Code Playgroud)

G. *_*eck 5

假设A如结尾处的注释中可重复显示,则cumsum的差异对于1和4之间(含1和4)之间的元素为TRUE,而下一个条件将消除端点。最后,我们用2代替剩下的TRUE位置。

replace(A, (cumsum(A == 1) - cumsum(A == 4)) & (A == "Na"), 2)
Run Code Online (Sandbox Code Playgroud)

给予:

 [1] "Na" "Na" "Na" "Na" "1"  "2"  "2"  "4"  "Na" "Na" "1"  "2"  "2"  "2"  "2" 
[16] "2"  "4"  "Na" "1"  "2"  "4"
Run Code Online (Sandbox Code Playgroud)

NA值

R区分大小写,并且Na与NA不同。问题中的样本数据显示的是Na值,而不是NA值,但是如果实际上是指具有NA值的数值向量(如AA以下注释中所述),则将表达式修改为如下所示:

replace(AA, cumsum(!is.na(AA) & AA == 1) - cumsum(!is.na(AA) & AA == 4) & is.na(AA), 2)
Run Code Online (Sandbox Code Playgroud)

给予:

[1] NA NA NA NA  1  2  2  4 NA NA  1  2  2  2  2  2  4 NA  1  2  4
Run Code Online (Sandbox Code Playgroud)

注意

A <- c("Na", "Na", "Na", "Na", "1", "Na", "Na", "4", "Na", "Na", 
"1", "Na", "Na", "Na", "Na", "Na", "4", "Na", "1", "Na", "4")

AA <- as.numeric(replace(A, A == "Na", NA))
Run Code Online (Sandbox Code Playgroud)


bre*_*usn 2

我确信这个问题有更好的解决方案,但这应该可以解决问题:

A <-
  c(NA, NA, NA, NA, 1, NA, NA, 4, NA, NA, 1, NA, NA, NA, NA, NA, 4, NA, 1, NA, 4)

replace <- FALSE

for (i in 1:length(A)) {
  if (!is.na(A[i])) {
    if (A[i] == 1) {
      start <- i + 1
      replace <- TRUE
    }
    if (A[i] == 4 & replace == TRUE) {
      A[start:(i - 1)] <- 2
      replace <- FALSE
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑:如果您只想在 1 和 3 之间没有其他内容(例如 3)的情况下替换 NA,您可以使用以下命令:

A <-
  c(NA, NA, NA, NA, 1, NA, 3, 4, NA, NA, 1, NA, NA, NA, NA, NA, 4, NA, 1, NA, 4)

replace <- FALSE

for (i in 1:length(A)) {
  if (!is.na(A[i])) {
    if (A[i] == 1) {
      start <- i + 1
      replace <- TRUE
    }
    if (A[i] == 4 & replace == TRUE) {
      A[start:(i - 1)] <- 2
      replace <- FALSE
    }
    if (A[i] != 4 & A[i] != 1){
      replace <- FALSE
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

输出:

> A
 [1] NA NA NA NA  1 NA  3  4 NA NA  1  2  2  2  2  2  4 NA  1  2  4
Run Code Online (Sandbox Code Playgroud)

如果您只想替换 NA 但保留 1 到 4 之间的其他值,请使用以下命令:

A <-
  c(NA, NA, NA, NA, 1, NA, 3, 4, NA, NA, 1, NA, NA, NA, NA, NA, 4, NA, 1, NA, 4)

replace <- FALSE

for (i in 1:length(A)) {
  if (!is.na(A[i])) {
    if (A[i] == 1) {
      start <- i + 1
      replace <- TRUE
    }
    if (A[i] == 4 & replace == TRUE) {
      sub <- A[start:(i - 1)]
      sub[is.na(sub)] <- 2
      A[start:(i - 1)] <- sub
      replace <- FALSE
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

输出:

> A
 [1] NA NA NA NA  1  2  3  4 NA NA  1  2  2  2  2  2  4 NA  1  2  4
Run Code Online (Sandbox Code Playgroud)