R数据框:用每组(另一列)替换第一个值(一个列)

时间:2018-07-24 11:45:29

标签: r dataframe replace

我想将have转换为want(请参见下文)。具体来说,我想将每个组(have$b)的第一个值(have$a))更改为一个公共值(此处为零)。

have <- data.frame(a=c(1,2,2,3,3,3), b=c(-5, -3, 2, -2, 6, 2))

want <- data.frame(a=c(1,2,2,3,3,3), b=c(0, 0, 2, 0, 6, 2))

3 个答案:

答案 0 :(得分:1)

因此,您需要一种建立分组变量并获取组内行号的方法。使用data.table可以很容易地做到这一点。

library(data.table)
have <- data.table(a=c(1,2,2,3,3,3), b=c(-5, -3, 2, -2, 6, 2))

data.table中,不仅有行/列索引。第二个参数实际上是我们可以对列进行突变的地方(id := 1:.N),第三个参数是分组参数(by = a)。在第二个参数中,:=表示替换内联,而.N是每个组中的行数。

have[,id := 1:.N, by=`a`]
#>    a  b id
#> 1: 1 -5  1
#> 2: 2 -3  1
#> 3: 2  2  2
#> 4: 3 -2  1
#> 5: 3  6  2
#> 6: 3  2  3

请注意id列如何计算a每组中的行。现在,您想将b替换为0,其中id == 1。在这里,第一个索引将过滤行,第二个参数为b分配一个值,但仅在满足过滤条件的地方。

have[id == 1, b := 0]
#>    a b id
#> 1: 1 0  1
#> 2: 2 0  1
#> 3: 2 2  2
#> 4: 3 0  1
#> 5: 3 6  2
#> 6: 3 2  3

最后,您可以将多余的id列分配为空。

have[,id := NULL]

答案 1 :(得分:1)

dplyr方法可能是

library(dplyr)

have %>%
  group_by(a) %>%
  mutate(b = case_when(row_number() == 1 ~ 0,    #replace 1st row value of each group to 0
                       TRUE ~ b))

给出

      a     b
  <dbl> <dbl>
1  1.00  0   
2  2.00  0   
3  2.00  2.00
4  3.00  0   
5  3.00  6.00
6  3.00  2.00


示例数据

have <- structure(list(a = c(1, 2, 2, 3, 3, 3), b = c(-5, -3, 2, -2, 
6, 2)), .Names = c("a", "b"), row.names = c(NA, -6L), class = "data.frame")

答案 2 :(得分:0)

受其他答案的启发,我想提供这种基本的R方法:

have$b[ c(1, diff(have$a))==1 ] <- 0

这还提供:

  a b
1 1 0
2 2 0
3 2 2
4 3 0
5 3 6
6 3 2