以下数据集为例:
id flag
1 1 Y
2 1
3 1
4 2
5 2 Y
6 3 Y
可重现的示例:
df <- data.frame(id=factor(c(1,1,1,2,2,3)), flag=c('Y','','','','Y','Y'))
如果任何 ID 存在标志 = Y,那么我希望所有该 ID 都具有标志"Y",因此上面的示例如下所示:
id flag
1 1 Y
2 1 Y
3 1 Y
4 2 Y
5 2 Y
6 3 Y
使用dplyr
的解决方案是
library(dplyr)
df %>%
group_by(id) %>%
mutate(flag_new = ifelse(any(flag == "Y"), "Y", as.character(flag)))
# A tibble: 6 x 3
# Groups: id [3]
id flag flag_new
<fct> <fct> <chr>
1 1 Y Y
2 1 "" Y
3 1 "" Y
4 2 "" Y
5 2 Y Y
6 3 "" ""
如果要保留组而不保留'Y'
,则必须使用不同的方法。
df <- data.frame(id=factor(c(1,1,1,2,2,3,3,3)), flag=c('Y','','','','Y','Z', 'G', ''))
# id flag
# 1 1 Y
# 2 1
# 3 1
# 4 2
# 5 2 Y
# 6 3 Z
# 7 3 G
# 8 3
# Thanks @akrun, for rewriting to avoid using "do" function
df %>%
group_by(id) %>%
mutate(flag_new = if(any(flag == "Y")) "Y" else as.character(flag))
# id flag flag_new
# <fct> <fct> <chr>
# 1 1 Y Y
# 2 1 "" Y
# 3 1 "" Y
# 4 2 "" Y
# 5 2 Y Y
# 6 3 Z Z
# 7 3 G G
# 8 3 "" ""
接受的答案:
df %>%
group_by(id) %>%
mutate(flag_new = ifelse(any(flag == "Y"), "Y", as.character(flag)))
# id flag flag_new
# <fct> <fct> <chr>
# 1 1 Y Y
# 2 1 "" Y
# 3 1 "" Y
# 4 2 "" Y
# 5 2 Y Y
# 6 3 Z Z
# 7 3 G Z
# 8 3 "" Z
或者使用data.table
,将 'data.frame' 转换为 'data.table' (setDT(df)
(,按 'id' 分组,获取行 id (.I
(,其中有任何 "Y"%in%
"flag" 列,将其用作i
并将 (:=
( 该 'id' 的 'flag' 元素分配给 "Y">
library(data.table)
setDT(df)[df[, .I["Y" %in% flag], id]$V1, flag := "Y"][]
# id flag
#1: 1 Y
#2: 1 Y
#3: 1 Y
#4: 2 Y
#5: 2 Y
#6: 3
数据
df <- data.frame(id=factor(c(1,1,1,2,2,3)), flag=c('Y','','','','Y',''))