【问题标题】:Replace values based on occurances根据出现替换值
【发布时间】:2021-09-05 07:27:30
【问题描述】:

我想用 x 列中的值替换数据框中的出现次数,而不管出现次数如何。我该怎么做?

数据结构:

期望的输出:

样本数据:

structure(list(x = c(10, 20, 30, 40, 50, 60), `04:00` = c(0, 
0, 0, 1, 0, 0), `04:10` = c(1, 0, 1, 0, 0, 0), `04:20` = c(0, 
0, 0, 1, 0, 0), `04:30` = c(0, 0, 0, 0, 0, 0), `04:40` = c(0, 
0, 0, 0, 0, 0)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -6L), spec = structure(list(cols = list(
    x = structure(list(), class = c("collector_double", "collector"
    )), `04:00` = structure(list(), class = c("collector_double", 
    "collector")), `04:10` = structure(list(), class = c("collector_double", 
    "collector")), `04:20` = structure(list(), class = c("collector_double", 
    "collector")), `04:30` = structure(list(), class = c("collector_double", 
    "collector")), `04:40` = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
"collector")), skip = 1L), class = "col_spec"))

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    我们可以通过循环across'x'以外的列来使用case_when,创建该列的值不等于x的逻辑条件,然后返回'x'值或列值

    library(dplyr)
    df1 %>% 
        mutate(across(-x, ~ case_when(. != 0 ~ x, TRUE ~ .)))
    

    -输出

    # A tibble: 6 x 6
          x `04:00` `04:10` `04:20` `04:30` `04:40`
      <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
    1    10       0      10       0       0       0
    2    20       0       0       0       0       0
    3    30       0      30       0       0       0
    4    40      40       0      40       0       0
    5    50       0       0       0       0       0
    6    60       0       0       0       0       0
    

    或者可以简化为

    df1 %>%
        mutate(across(-x, ~ (. > 0) * x))
    

    或使用base R

    df1[-1] <-  (df1[-1] > 0)* df1$x[row(df1[-1])]
    

    【讨论】:

      【解决方案2】:

      applyifelse 的基本方法:

      apply(df, 2, function(i) ifelse(i!=0, df$x, 0))
      
            x 04:00 04:10 04:20 04:30 04:40
      [1,] 10     0    10     0     0     0
      [2,] 20     0     0     0     0     0
      [3,] 30     0    30     0     0     0
      [4,] 40    40     0    40     0     0
      [5,] 50     0     0     0     0     0
      [6,] 60     0     0     0     0     0
      

      【讨论】:

        【解决方案3】:

        就是这样

        library(dplyr)
        mutate(df, across(!x, ~ as.logical(.) * x))
        
        # A tibble: 6 x 6
              x `04:00` `04:10` `04:20` `04:30` `04:40`
          <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
        1    10       0      10       0       0       0
        2    20       0       0       0       0       0
        3    30       0      30       0       0       0
        4    40      40       0      40       0       0
        5    50       0       0       0       0       0
        6    60       0       0       0       0       0
        

        【讨论】:

          【解决方案4】:

          一种方法是使用 use apply。我们可以使用一个简单的函数,它接收一个向量并将该向量的任何非零元素替换为该向量的x 值,然后我们将该函数应用于数据帧的每一行。

          唯一棘手的是应用输出不是我们想要的格式,但快速转置和强制转换为数据帧让我们重新开始工作。

          apply(X = x, MARGIN=1, FUN = function(r){r[r>0] = r['x']; r}) %>%
            t() %>%
            as.data.frame()
          

          LC-datascientists 解决方案可能更好。 ifelse 有时可能会出现问题,但在这里应该很好。另外,它会比我在大型数据集上的解决方案更快,因为它应用于列而不是行。

          【讨论】:

            猜你喜欢
            • 2022-01-19
            • 1970-01-01
            • 2016-10-10
            • 2021-09-23
            • 2021-06-08
            • 2021-02-20
            • 2019-03-22
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多