如何在一个特定值出现后使一行中的所有值都在R中NA

xu3bshqb  于 2023-02-17  发布在  其他
关注(0)|答案(3)|浏览(126)

我在R中有这样的数据:

T1 <- c(0,0,0,0,0)
T2 <- c(1,0,0,0,0)
T3 <- c(0,1,0,0,0)
T4 <- c(1,1,0,NA,1)
T5 <- c(0,1,0,NA,0)
df <- data.frame(T1,T2,T3,T4,T5)

  T1 T2 T3 T4 T5
1  0  1  0  1  0
2  0  0  1  1  1
3  0  0  0  0  0
4  0  0  0 NA NA
5  0  0  0  1  0

我希望做的是把第一个“1”出现后的所有值都变成NA,所以它看起来像这样:

T1 T2 T3 T4 T5
1  0  1 NA NA NA
2  0  0  1 NA NA
3  0  0  0  0  0
4  0  0  0 NA NA
5  0  0  0  1 NA

有什么建议吗?谢谢!

vm0i2vca

vm0i2vca1#

我们可以使用rowCumsums创建一个逻辑向量,然后进行赋值

library(matrixStats)
df[rowCumsums(rowCumsums(df == 1)) > 1] <- NA
  • 输出
> df
  T1 T2 T3 T4 T5
1  0  1 NA NA NA
2  0  0  1 NA NA
3  0  0  0  0  0
4  0  0  0 NA NA
5  0  0  0  1 NA
8i9zcol2

8i9zcol22#

使用apply从底数R得到which.max的第一个1
first1 = which.max(x == 1)
生成一个可排序的整数,并将不在序列中的值划分为子集。mySeq <-ifelse(first1 == 1, length(x), first1)
子集值为NA
x[-seq(mySeq)] <- NA
返回值

df[] <- t(apply(df, 1, \(x) {
  first1 = which.max(x == 1)
  mySeq <-ifelse(first1 == 1, length(x), first1)
  x[-seq(mySeq)] <- NA
  x
  }))
T1 T2 T3 T4 T5
1  0  1 NA NA NA
2  0  0  1 NA NA
3  0  0  0  0  0
4  0  0  0 NA NA
5  0  0  0  1 NA
vzgqcmou

vzgqcmou3#

下面是第一次透视到长格式的替代方法:

library(dplyr)
library(tidyr)

df %>% 
  pivot_longer(everything()) %>% 
  group_by(group =as.integer(gl(n(),max(parse_number(name)),n()))) %>% 
  mutate(value1 = ifelse(1:n() > which(value == 1)[1], NA, value),
         y = sum(value, na.rm = TRUE)) %>% 
  mutate(value = ifelse(y == 0, value, value1), .keep="unused") %>% 
  pivot_wider(names_from = name, values_from = value)
group    T1    T2    T3    T4    T5
  <int> <dbl> <dbl> <dbl> <dbl> <dbl>
1     1     0     1    NA    NA    NA
2     2     0     0     1    NA    NA
3     3     0     0     0     0     0
4     4     0     0     0    NA    NA
5     5     0     0     0     1    NA

相关问题