【问题标题】:Shift values in a dataframe in R在R中的数据框中移动值
【发布时间】:2018-08-06 15:25:20
【问题描述】:

我有一个数据框:

dt <- read.table(text = "
0 344 34 0 0
0 350 16 0 0
0 366 11 0 0
0 376 8  0 0
0 380 28 0 0
0 397 55 0 0
0 398 45 0 0  
0 400 19 0 0 
0 402 30 0 0")

我想随机将1/3的行向右移动一列,例如:

dt1 <- read.table(text = "
0 344 34 0 0
0 350 16 0 0
0 0 366 11 0 
0 376 8  0 0
0 0 380 28 0 
0 0 397 55 0
0 398 45 0 0  
0 400 19 0 0 
0 402 30 0 0")

是否可以有一个参数来选择班次?如果我想移动两列、三列或四列而不是一列。

【问题讨论】:

    标签: r dataframe shift


    【解决方案1】:

    这里有两种可能的解决方案,如果你愿意,可以将它们包装成一个函数。

    第一个解决方案的理念是转置您的数据集并将行用作列,以便您可以使用mutate_at(您随机选择的行)然后再次转置:

    dt <- read.table(text = "
    0 344 34 0 0
    0 350 16 0 0
    0 366 11 0 0
    0 376 8  0 0
    0 380 28 0 0
    0 397 55 0 0
    0 398 45 0 0  
    0 400 19 0 0 
    0 402 30 0 0")
    
    library(tidyverse)
    
    # for reproducibility
    set.seed(4)
    
    # pick number of rows to shift
    num_rows = round(1/3 * nrow(dt))
    
    # sample position of those rows
    rows = sample(1:nrow(dt), num_rows)
    
    # specify number of shifts
    num_shifts = 2
    
    
    t(dt) %>%                           # transpose dataset
      data.frame() %>%                  # update to data frame
      mutate_at(rows, ~lag(., num_shifts, default = 0L)) %>%  # use the selected row positions and the selected number of shifts to apply this function
      t() %>%                           # transapose data again
      data.frame(., row.names = NULL)   # update to dataframe
    
    #   X1  X2 X3  X4 X5
    # 1  0   0  0 344 34
    # 2  0 350 16   0  0
    # 3  0   0  0 366 11
    # 4  0 376  8   0  0
    # 5  0 380 28   0  0
    # 6  0   0  0 397 55
    # 7  0 398 45   0  0
    # 8  0 400 19   0  0
    # 9  0 402 30   0  0
    

    还有一种替代方法,不转置,但使用 map2 处理行:

    dt %>%
      group_by(id = row_number()) %>%   # group by row id
      nest() %>%                        # nest data
      mutate(d = map2(id, data, ~if(.x %in% rows) lag(.y, num_shifts, default = 0L) else .y)) %>%  # apply shift to selected row positions/ids
      unnest(d) %>%                     # unnest data
      select(-id, -data)                # remove unnecessary columns
    
    # # A tibble: 9 x 5
    #      V1    V2    V3    V4    V5
    #   <int> <int> <int> <int> <int>
    # 1     0     0     0   344    34
    # 2     0   350    16     0     0
    # 3     0     0     0   366    11
    # 4     0   376     8     0     0
    # 5     0   380    28     0     0
    # 6     0     0     0   397    55
    # 7     0   398    45     0     0
    # 8     0   400    19     0     0
    # 9     0   402    30     0     0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-13
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      • 1970-01-01
      • 2019-10-31
      • 2016-09-07
      • 1970-01-01
      相关资源
      最近更新 更多