添加一列,以标识其他列定义的每个组的第一行

时间:2018-07-13 02:49:17

标签: r dataframe

我有一个数据集data,其列为X0value,并希望在排序后按X0进行分组,并为每组的第一行生成一个指标看起来像下面的first列:

   X0  value first
 1  A  26509   1
 2  A  28146   0
 3  B  19950   1
 4  B  19981   0
 5  B  20304   0

3 个答案:

答案 0 :(得分:2)

执行此操作的多种方法,dplyr可能是

library(dplyr)
df %>%
 group_by(X0) %>%
  mutate(new_first = if_else(row_number() == 1, 1, 0))

#  X0    value first new_first
#  <fct> <int> <int>     <dbl>
#1 A     26509     1      1.00
#2 A     28146     0      0   
#3 B     19950     1      1.00
#4 B     19981     0      0   
#5 B     20304     0      0   

基本R ave方法中可以使用相同的逻辑

df$new_first <- ave(df$value, df$X0, FUN = function(x)
                 ifelse(seq_along(x) == 1, 1, 0))


df
#  X0 value first new_first
#1  A 26509     1         1
#2  A 28146     0         0
#3  B 19950     1         1
#4  B 19981     0         0
#5  B 20304     0         0

更简洁

as.integer(ave(df$value, df$X0, FUN = seq_along) == 1)
#[1] 1 0 1 0 0

答案 1 :(得分:2)

另一种dplyr方法。

library(dplyr)

dat2 <- dat %>%
  group_by(X0) %>%
  mutate(first = as.integer(row_number() == 1L)) %>%
  ungroup()
dat2
# # A tibble: 5 x 3
#   X0    value first
#   <chr> <int> <int>
# 1 A     26509     1
# 2 A     28146     0
# 3 B     19950     1
# 4 B     19981     0
# 5 B     20304     0

或使用data.table软件包。

library(data.table)

setDT(dat)

dat2 <- dat[, first := as.integer(rowid(X0) == 1L)]
dat2[]
#    X0 value first
# 1:  A 26509     1
# 2:  A 28146     0
# 3:  B 19950     1
# 4:  B 19981     0
# 5:  B 20304     0

数据

dat <- read.table(text = "X0  value
 1  A  26509
                  2  A  28146
                  3  B  19950
                  4  B  19981
                  5  B  20304",
                  header = TRUE, stringsAsFactors = FALSE)

答案 2 :(得分:1)

我们可以使用duplicated中的base R来获取基于'X0'重复值的逻辑向量,并使用as.integer将其转换为二进制数

df1$first <- as.integer(!duplicated(df1$X0))
df1$first
#[1] 1 0 1 0 0

如果未“ sort”编辑“值”列

library(dplyr)
df1 %>% 
    group_by(X0) %>%
    mutate(first =  as.integer(value == min(value)))

数据

df1 <- structure(list(X0 = c("A", "A", "B", "B", "B"), value = c(26509L, 
28146L, 19950L, 19981L, 20304L), first = c(1L, 0L, 1L, 0L, 0L
)), .Names = c("X0", "value", "first"), class = "data.frame",
 row.names = c("1", "2", "3", "4", "5"))