tidyverse 中的列索引,适用于循环

问题描述 投票:0回答:2

嘿嘿,

我想将一个 for 循环转换为 tidyverse 工作流程,因为我通常遵循 tidyverse 方法并且喜欢使用管道工作流程。我可以使用 for 循环轻松实现我想要的内容。

这是一个最小的可重现示例,其中我按每行标识第一次出现 1 的列(列数)。然后,我用它来索引我的矩阵,并在第一个 1 之前的每列中设置 NA。

# set seed
set.seed(10)

# create matrix of 0 and 1
matrix<-matrix(rbinom(100, 1, 0.4),nrow=10,ncol=10)

# get first column not being a zero (index)
first <- apply(matrix, 1, function(x) min(which(x !=0)))

# set all column before the indexed column to NA
for (i in 1:nrow(matrix)){
  
  if(first[i] > 1) matrix[i, 1:(first[i]-1)] <- NA
  
}

matrix
for-loop matrix dplyr tidyverse data-manipulation
2个回答
1
投票

这是用

tidyverse
做同样事情的一种方法:

matrix |>
  as.data.frame() |>
  rowwise() |>
  mutate(first = which.max(c_across(everything())),
         across(-first, ~ if_else(as.numeric(str_extract(cur_column(), "\\d+")) < first, NA, .))) |> # this is quite janky. If anyone knows a way of selecting column numbers within an across call, please comment with it
  ungroup() |> 
  select(-first)

虽然这很糟糕。如果有人知道在跨调用中选择列号的方法,请评论! :-)


0
投票

如果您正在使用

tidyverse
,我建议将矩阵从“宽”格式转换为“长”格式,然后执行您想要的任何操作。 “长”格式被认为是“整齐”。

这里的核心概念是使用

cumsum
返回原始行的累积和。如果为零,则将其替换为
NA
,否则不要更改任何内容。

library(tidyverse)

as.data.frame(matrix) %>% 
  mutate(rn = row_number()) %>% 
  pivot_longer(-rn) %>% 
  mutate(value = ifelse(cumsum(value) == 0, NA, value), .by = rn) %>% 
  pivot_wider() %>% 
  select(-rn)

# A tibble: 10 × 10
      V1    V2    V3    V4    V5    V6    V7    V8    V9   V10
   <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
 1    NA     1     1     0     0     0     0     0     1     0
 2    NA    NA     1     0     0     1     0     0     0     1
 3    NA    NA     1     0     0     0     0     1     0     0
 4     1     0     0     1     1     0     0     0     1     0
 5    NA    NA    NA    NA    NA    NA     1     0     0     0
 6    NA    NA     1     1     0     0     1     0     0     1
 7    NA    NA     1     1     0     0     0     0     1     0
 8    NA    NA    NA     1     0     0     0     1     0     0
 9     1     0     1     1     0     0     0     0     0     1
10    NA     1     0     0     1     0     0     0     0     0
© www.soinside.com 2019 - 2024. All rights reserved.