根据条件分配多个行值

Assign multiple row values based on condition

我有一个看起来像这样的数据框

   sl_no      A_1     A_2    A_3     A_4     A_5      A_6
    1          0       0      1       0       1        1
    2          1       0      0       1       0        1
    3          1       1      0       0       0        0

等等大约 300 行。我想要做的是只保留每行 'A_' 变量中的第一个“1”。所以最终的数据集应该是这样的

  sl_no      A_1     A_2    A_3     A_4     A_5      A_6
    1          0       0      1       0       0        0
    2          1       0      0       0       0        0
    3          1       0      0       0       0        0

我该怎么做? for循环中的if else语句?

这是一个带有自定义函数的基本 R 选项 -

keep_only_first_one <- function(x) {
  #get the position of first 1
  inds <- match(1, x)
  #If the positions is not the last one, 
  #change all the values after 1st one to 0.
  if(inds < length(x)) x[(inds + 1):length(x)] <- 0
  x
}
df[-1] <- t(apply(df[-1], 1, keep_only_first_one))
df

#  sl_no A_1 A_2 A_3 A_4 A_5 A_6
#1     1   0   0   1   0   0   0
#2     2   1   0   0   0   0   0
#3     3   1   0   0   0   0   0

这假设您要将此函数应用于除第 1 列(因此为 -1)之外的所有列。如果你想 select 基于它的名称的列,你可以使用 -

cols <- grep('^A_', names(df))
df[cols] <- t(apply(df[cols], 1, keep_only_first_one))
df

另一个可能的解决方案:

df <- data.frame(
  sl_no = c(1L, 2L, 3L),
  A_1 = c(0L, 1L, 1L),
  A_2 = c(0L, 0L, 1L),
  A_3 = c(1L, 0L, 0L),
  A_4 = c(0L, 1L, 0L),
  A_5 = c(1L, 0L, 0L),
  A_6 = c(1L, 1L, 0L)
)

df[-1] <-
 t(apply(df[-1], 1, \(x)  {y = which(x == 1); x[1:length(x) != min(y)] <- 0; x}))
df

#>   sl_no A_1 A_2 A_3 A_4 A_5 A_6
#> 1     1   0   0   1   0   0   0
#> 2     2   1   0   0   0   0   0
#> 3     3   1   0   0   0   0   0