我想创建一个虚拟变量,如果在两个或多个不同年龄组中观察到个体,则取值为1,否则为0。
是否有人能够这样做并可以向我解释?
一个小例子可能是:
set.seed(123)
df <- data.frame(id = sample(1:10, 30, replace = TRUE),
agegroup = sample(c("5054", "5559", "6065"), 30, replace = TRUE))
预期产量:
id agegroup dummy
3 6065 1
8 6065 1
5 6065 1
9 6065 1
10 5054 1
1 5559 0
6 6065 1
9 5054 1
6 5054 1
5 5054 1
10 5054 1
5 5559 1
7 5559 1
6 5559 1
2 5054 1
9 5054 1
3 5054 1
1 5559 0
4 5054 0
10 6065 1
9 5054 1
7 5559 1
7 6065 1
10 5054 1
7 5559 1
8 5054 1
6 5054 1
6 6065 1
3 6065 1
2 5559 1
答案 0 :(得分:5)
选项是使用dplyr::group_by(id)
并计算unique
年龄组。您的数据包含id
和agegroup
组合的重复行。
修改:更新了@Henrik
library(dplyr)
df %>% group_by(id) %>%
mutate(dummy = as.integer(n_distinct(agegroup) > 1))
# # A tibble: 30 x 3
# # Groups: id [10]
# id agegroup dummy
# <int> <fctr> <int>
# 1 3 6065 1
# 2 8 6065 1
# 3 5 6065 1
# 4 9 6065 1
# 5 10 5054 1
# 6 1 5559 0
# 7 6 6065 1
# 8 9 5054 1
# 9 6 5054 1
# 10 5 5054 1
# # ... with 20 more rows
答案 1 :(得分:4)
这是data.table
解决方案
library('data.table')
setDT(df)[, N := uniqueN(agegroup), by = .(id)][N == 1, N := 0 ][N > 1, N := 1]
或
setDT(df)[, N := as.integer( uniqueN(agegroup) > 1 ), by = .(id)]
答案 2 :(得分:3)
使用base R可以使用ave
执行此操作。您只需要将factor
或character
变量agegroup
强制转换为numeric
。
df$dummy <- ave(as.numeric(as.character(df$agegroup)), df$id, FUN = function(x) length(unique(x)) != 1)
head(df, 10)
# id agegroup dummy
#1 3 6065 1
#2 8 6065 1
#3 5 6065 1
#4 9 6065 1
#5 10 5054 1
#6 1 5559 0
#7 6 6065 1
#8 9 5054 1
#9 6 5054 1
#10 5 5054 1
答案 3 :(得分:3)
另一个dplyr
解决方案。 n_distinct
是计算不同的数字。 (dummy > 1) + 0L
用于评估数字是否大于1并转换为整数。
library(dplyr)
df2 <- df %>%
group_by(id) %>%
mutate(dummy = n_distinct(agegroup)) %>%
mutate(dummy = (dummy > 1) + 0L) %>%
ungroup()
df2
# # A tibble: 30 x 3
# id agegroup dummy
# <int> <fct> <int>
# 1 3 6065 1
# 2 8 6065 1
# 3 5 6065 1
# 4 9 6065 1
# 5 10 5054 1
# 6 1 5559 0
# 7 6 6065 1
# 8 9 5054 1
# 9 6 5054 1
# 10 5 5054 1
# # ... with 20 more rows
答案 4 :(得分:2)
另一个带有ifelse
的基本R解决方案:
df$dummy <- ifelse(df$id %in% names(which(lengths(tapply(df$agegroup, df$id, unique)) > 1)), 1, 0)
head(df)
id agegroup dummy
1 3 6065 1
2 8 6065 1
3 5 6065 1
4 9 6065 1
5 10 5054 1
6 1 5559 0
答案 5 :(得分:0)
在基础R
(也不保留行顺序)或dplyr
(保留行顺序)
基础R
merge(df, transform(unique(df),dummy = as.numeric(duplicated(id)|duplicated(id,fromLast = T))))
# id agegroup dummy
# 1 1 5559 0
# 2 1 5559 0
# 3 10 5054 1
# 4 10 5054 1
# 5 10 5054 1
# 6 10 6065 1
# 7 2 5054 1
# 8 2 5559 1
# 9 3 5054 1
# 10 3 6065 1
# 11 3 6065 1
# 12 4 5054 0
# 13 5 5054 1
# 14 5 5559 1
# 15 5 6065 1
# 16 6 5054 1
# 17 6 5054 1
# 18 6 5559 1
# 19 6 6065 1
# 20 6 6065 1
# 21 7 5559 1
# 22 7 5559 1
# 23 7 5559 1
# 24 7 6065 1
# 25 8 5054 1
# 26 8 6065 1
# 27 9 5054 1
# 28 9 5054 1
# 29 9 5054 1
# 30 9 6065 1
<强> dplyr 强>
library(dplyr)
df %>%
distinct %>%
mutate(dummy = as.numeric(duplicated(id)|duplicated(id,fromLast = T))) %>%
inner_join(df,.)
# id agegroup dummy
# 1 3 6065 1
# 2 8 6065 1
# 3 5 6065 1
# 4 9 6065 1
# 5 10 5054 1
# 6 1 5559 0
# 7 6 6065 1
# 8 9 5054 1
# 9 6 5054 1
# 10 5 5054 1
# 11 10 5054 1
# 12 5 5559 1
# 13 7 5559 1
# 14 6 5559 1
# 15 2 5054 1
# 16 9 5054 1
# 17 3 5054 1
# 18 1 5559 0
# 19 4 5054 0
# 20 10 6065 1
# 21 9 5054 1
# 22 7 5559 1
# 23 7 6065 1
# 24 10 5054 1
# 25 7 5559 1
# 26 8 5054 1
# 27 6 5054 1
# 28 6 6065 1
# 29 3 6065 1
# 30 2 5559 1