R:更改主题中的重复值

R: Changing Duplicate Values Within Subjects

 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

关于我如何能够完成此任务的任何建议?

谢谢!

使用 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)

有点类似于已经提供的解决方案,但不算。这由两个解决方案组成:

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 的列组合定义的块。从这里开始,剩下的就很简单了:从 0 开始,将 Time 列中的值增加 0.5,这样的序列的长度与块的长度相同。

希望这有用。

这里有一个 base R 选项和 duplicated。我们根据 '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