【问题标题】:R: Changing Duplicate Values Within SubjectsR:更改主题内的重复值
【发布时间】:2018-05-08 19:07:00
【问题描述】:
 Subj  Trial  Time
1 A      1     250
2 A      2     250
3 A      3     280
4 B      1     250
5 B      2     270
6 B      3     290

以上是我正在处理的数据示例。我有不同的受试者 (Subj) 执行同一组试验 (Trial)。不幸的是,当试验事件快速连续发生时,我的设备将打印相同的时间值(请参阅第 1 行和第 2 行的时间列)。

我不能让相同的主题有重复的时间值,但是,不同的主题有相同的时间值是可以的。因此,我需要一种有条件地更改重复项的方法,以便仅更改特定主题内的时间重复项。

理想情况下,我想将上面的示例更改为如下所示:

 Subj  Trial  Time
1 A      1     250
2 A      2     250.5
3 A      3     280
4 B      1     250
5 B      2     270
6 B      3     290

关于我如何能够做到这一点的任何建议?

谢谢!

【问题讨论】:

    标签: r duplicates conditional


    【解决方案1】:

    这是带有duplicatedbase R 选项。我们根据“Subj”、“Time”列创建重复元素的逻辑索引,然后通过将 0.5 添加到这些元素来为这些元素分配“Time”值。

    i1 <- duplicated(df1[c('Subj', 'Time')])
    df1$Time[i1] <- df1$Time[i1] + 0.5
    df1
    #  Subj Trial  Time
    #1    A     1 250.0
    #2    A     2 250.5
    #3    A     3 280.0
    #4    B     1 250.0
    #5    B     2 270.0
    #6    B     3 290.0
    

    【讨论】:

      【解决方案2】:

      有点类似于已经提供的解决方案,但不计算在内。这包括两个解决方案:

      base R:

      do.call(rbind, lapply(split(df, list(df$Subj, df$Time)), function(x) {
          x$Time <- x$Time + seq(0, by=0.5, length.out=nrow(x))
          x
      }))
      

      tidyverse

      library(dplyr)
      
      
      df %>%
          group_by(Subj, Time) %>%
          mutate(Time2 = Time + seq(0, by=0.5, length.out=n()))
      

      它们都应该产生类似于以下的内容:

      #  Subj Trial Time 
      #  A    1     250.0
      #  A    2     250.5
      #  B    1     250.0
      #  B    2     270.0
      #  A    3     280.0
      #  B    3     290.0
      

      关键是将您的数据框拆分为由SubjTime 的列组合定义的块。从这里开始,剩下的就很简单了:将Time 列中的值从0 开始递增0.5,这样一个序列的长度与块的长度相同。

      我希望这证明有用。

      【讨论】:

      • 这个解决方案也很好用!非常感谢您的回答。
      【解决方案3】:

      使用dplyr 的解决方案。我们可以通过SubjTime对数据进行分组,统计出现次数,如果出现次数大于1,则通过添加0.5来更改Time

      library(dplyr)
      
      dt2 <- dt %>%
        group_by(Subj, Time) %>%
        mutate(Count = row_number()) %>%
        ungroup() %>%
        mutate(Time = ifelse(Count > 1, Time + 0.5, Time)) %>%
        select(-Count)
      dt2
      # # A tibble: 6 x 3
      #    Subj Trial  Time
      #   <chr> <int> <dbl>
      # 1     A     1 250.0
      # 2     A     2 250.5
      # 3     A     3 280.0
      # 4     B     1 250.0
      # 5     B     2 270.0
      # 6     B     3 290.0
      

      数据

      dt <- read.table(text = " Subj  Trial  Time
      1 A      1     250
      2 A      2     250
      3 A      3     280
      4 B      1     250
      5 B      2     270
      6 B      3     290",
                       header = TRUE, stringsAsFactors = FALSE)
      

      【讨论】:

      • 非常感谢!这个解决方案完美!虽然,起初我在让它工作时遇到了一些麻烦......我没有附加我的数据框,而是通过 dt$Subj 或 dt$Time 调用列。这导致我在第二次变异时出现“意外 =”错误。在我附加数据框并单独调用列之后(如您在示例中所示),它起作用了!再次感谢!
      猜你喜欢
      • 2020-09-01
      • 2016-06-28
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      • 2013-08-20
      • 2019-12-11
      • 1970-01-01
      • 2015-01-29
      相关资源
      最近更新 更多