使用dplyr根据列名的子字符串替换缺少的列

ef1yzkbh  于 2023-02-06  发布在  其他
关注(0)|答案(2)|浏览(142)

我想根据start_value和end_value将某些列替换为NA。例如:

  • 第一行将保持这样,因为缺少start_value和end_value;
  • 第二行将替换为missing,从第一列(值.1)到第三列(值.3);
  • 从第二列(值2)到第三列(值3),第三行将被替换为缺失,等等。

Dataframe 示例:

df <- data.frame(id=c(1:4),value.1=c(0,1,1,0), value.2=c(rep(0,3),1), value.3=c(1,1,1,0), start_value=c(NA,1,2,NA),end_value=c(NA,3,3,NA))
id value.1  value.2  value.3  start_value  end_value
1     0        0       1         NA           NA
2     1        0       1         1            3
3     1        0       1         2            3
4     0        1       0         NA           NA

我想得到一个最终的df,如下所示:

id value.1  value.2  value.3  
    1     0        0       1      
    2     NA       NA      NA       
    3     1        NA      NA       
    4     0        1       0
5f0d552i

5f0d552i1#

下面是使用apply的方法:

as.data.frame(
  t(apply(df, 1, function(x) {
  start <- x[5]
  end  <- x[6]
  if (anyNA(c(start, end))){
    x[1:4]
  } else {
    x[2:4][start:end] <- NA
    x[1:4]
  }
})))

  id value.1 value.2 value.3
1  1       0       0       1
2  2      NA      NA      NA
3  3       1      NA      NA
4  4       0       1       0
qvk1mo1f

qvk1mo1f2#

使用row/column索引的base R方法

i1 <- complete.cases(df[5:6])
lst1 <- do.call(Map, c(f = `:`, unname(df[i1,5:6])))
df[i1, 2:4][cbind(rep(seq_along(lst1), lengths(lst1)), unlist(lst1))] <- NA
  • 输出
> df[1:4]
  id value.1 value.2 value.3
1  1       0       0       1
2  2      NA      NA      NA
3  3       1      NA      NA
4  4       0       1       0

或者使用tidyverse

library(dplyr)
library(stringr)
nm1 <- str_subset(names(df), "value\\.")
 df %>%
   transmute(id, across(starts_with('value'), 
   ~ {
   ind <- match(cur_column(), nm1)
   replace(.x, ind >= start_value & ind <=end_value, NA)
}))
  • 输出
id value.1 value.2 value.3
1  1       0       0       1
2  2      NA      NA      NA
3  3       1      NA      NA
4  4       0       1       0

相关问题