首页 > 解决方案 > 给定具有条件的数据框,如何改变列?

问题描述

我有一个两列数据框。第一列是时间戳,第二列是某个值。例如:

library(tidyverse)
set.seed(123)
data_df <- tibble(t = 1:15,
                  value = sample(letters, 15))

我有另一个数据框,它指定需要更新的时间戳范围及其相应的值。例如:

criteria_df <- tibble(start = c(1, 3, 7),
                      end = c(2, 5, 10),
                      value = c('a', 'b', 'c')
                      )

这意味着我需要改变 data_df 中的值列,使其从 t=1 到 t=2 的值是“a”,从 t=3 到 t=5 是“b”,从 t=7 到 t=10是'c'。

在 R 中推荐的方法是什么?

我能想到的唯一方法是循环criteria_df中的每一行并在过滤t列之后改变data_df中的值列,如下所示:

library(iterators)
library(foreach)

foreach(row = row_iter, .combine = c) %do% {
  seg_start = row$start
  seg_end = row$end
  new_value = row$value

  data_df %<>%
    mutate(value = if_else(between(t, seg_start, seg_end),
                                    new_value,
                                    value))
  NULL
}

标签: rdplyr

解决方案


我们可以做一个两步的基本 R 解决方案,我们首先找到位于 and 范围内的值,criteria_df start然后如果匹配end则替换data_df value它的等效criteria_df'svalue或保持原样。

inds <- sapply(data_df$t, function(x) criteria_df$value[x >= criteria_df$start 
                                                      & x <= criteria_df$end])

data_df$value <- unlist(ifelse(lengths(inds) > 0, inds, data_df$value))
data_df

#      t value
#   <int> <chr>
# 1     1 a    
# 2     2 a    
# 3     3 b    
# 4     4 b    
# 5     5 b    
# 6     6 a    
# 7     7 c    
# 8     8 c    
# 9     9 c    
#10    10 c    
#11    11 p    
#12    12 g    
#13    13 r    
#14    14 s    
#15    15 b    

推荐阅读