R中每个重复值增加1

时间:2017-04-04 01:08:13

标签: r

我正在尝试在R中找到一种正确的方法来查找重复值,并将值1添加到按ID分组的每个后续重复值中。例如:

data=data.table(id=c('1','1','1','1','1','2','2','2'),value=c(95,100,101,101,101,20,35,38))
data$new_value <- ifelse(data[,data$value] == lag(data$value,1), lag(data$value,1)+1 ,data$value)
data$desired_value <- c(95,100,101,102,103,20,35,38)

制作:

   id value new_value desired_value
1:  1    95        NA            95
2:  1   100       100           100
3:  1   101       101           101
4:  1   101       102           102
5:  1   101       102           103
6:  2    20        20            20
7:  2    35        35            35
8:  2    38        38            38

我尝试使用ifelse执行此操作,但它不能递归地工作,因此它仅适用于以下行,而不适用于任何后续行。此外,lag函数会导致我失去value中的第一个值。

我见过包含make.namesmake.unique字符变量的示例,但无法找到重复数值的解决方案。

背景:我正在进行生存分析,我发现在我的数据中,停止时间是相同的,所以我需要通过添加1来使其唯一(停止时间以秒为单位)。

4 个答案:

答案 0 :(得分:6)

这是一次尝试。您实际上是按idvalue进行分组并添加0:(length(value)-1)。所以:

data[, onemore := value + (0:(.N-1)), by=.(id, value)]

#   id value new_value desired_value onemore
#1:  1    95        96            95      95
#2:  1   100       101           100     100
#3:  1   101       102           101     101
#4:  1   101       102           102     102
#5:  1   101       102           103     103
#6:  2    20        21            20      20
#7:  2    35        36            35      35
#8:  2    38        39            38      38

答案 1 :(得分:5)

使用基数R,我们可以使用ave,其中我们获取每个组的第一个值,并基本上在该组中添加该行的行号。

data$value1 <- ave(data$value, data$id, data$value, FUN = function(x)
                                                      x[1] + seq_along(x) - 1)

#   id value new_value desired_value value1
#1:  1    95        96            95     95
#2:  1   100       101           100    100
#3:  1   101       102           101    101
#4:  1   101       102           102    102
#5:  1   101       102           103    103
#6:  2    20        21            20     20
#7:  2    35        36            35     35
#8:  2    38        39            38     38

答案 2 :(得分:1)

以下是tidyverse

的一个选项
library(dplyr)
data %>%
    group_by(id, value) %>%
    mutate(onemore = value + row_number()-1)
#     id value onemore
#  <chr> <dbl>   <dbl>
#1     1    95      95
#2     1   100     100
#3     1   101     101
#4     1   101     102
#5     1   101     103
#6     2    20      20
#7     2    35      35
#8     2    38      38

或者我们可以在没有匿名函数调用的情况下使用base R

data$onemore <- with(data, value + ave(value, id, value, FUN =seq_along)-1)
data$onemore
#[1]  95 100 101 102 103  20  35  38

答案 3 :(得分:1)

为了避免(潜在的代价高昂的)by,您可以使用 rowid

data[, res := value + rowid(id, value) - 1]
# data
#    id value new_value desired_value res
# 1:  1    95        96            95  95
# 2:  1   100       101           100 100
# 3:  1   101       102           101 101
# 4:  1   101       102           102 102
# 5:  1   101       102           103 103
# 6:  2    20        21            20  20
# 7:  2    35        36            35  35
# 8:  2    38        39            38  38