我想将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))
答案 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