我对R很新,并且遇到了关于唯一值的for循环的问题。
使用df:
id = c(1,2,2,3,3,4)
rank = c(1,2,1,3,3,4)
df = data.frame(id, rank)
我跑:
df$dg <- logical(6)
for(i in unique(df$id)){
ifelse(!unique(df$rank), df$dg ==T, df$dg == F)
}
我试图将$ dg变量标记为T,前提是每个唯一ID的排名不同,如果每个id中的排名相同,则为F.
我没有收到任何错误,但即使我应该得到一个混合,我只获得$ dg的所有值。
我还使用了以下循环,结果相同:
for(i in unique(df$id)){
ifelse(length(unique(df$rank)), df$dg ==T, df$dg == F)
}
我已经阅读了其他类似的帖子,但这个建议对我的案子没有用。
来自评论:
如果给定id的等级发生了任何变化,我想为所有id实例标记dg TRUE。我想找一个在1到13个实例之间的给定ID,如果不同实例的等级,则标记dg为TRUE。
答案 0 :(得分:2)
在澄清之后,OP提供了这个特定案例的解决方案:
library(dplyr)
df %>%
group_by(id) %>%
mutate(dg = ifelse( length(unique(rank))>1 | n() == 1, T, F))
对于另一个也有id的数据集,它有重复但也有非重复的等级(如下所示),这将是输出:
df2 %>%
group_by(id) %>%
mutate(dg = ifelse( length(unique(rank))>1 | n() == 1, T, F))
#:OUTPUT:
# Source: local data frame [9 x 3]
# Groups: id [5]
#
# # A tibble: 9 x 3
# id rank dg
# <dbl> <dbl> <lgl>
# 1 1 1 TRUE
# 2 2 2 TRUE
# 3 2 1 TRUE
# 4 3 3 FALSE
# 5 3 3 FALSE
# 6 4 4 TRUE
# 7 5 1 TRUE
# 8 5 1 TRUE
# 9 5 3 TRUE
<强> 数据-NO-2: 强>
df2 <- structure(list(id = c(1, 2, 2, 3, 3, 4, 5, 5, 5), rank = c(1, 2, 1, 3, 3, 4, 1, 1, 3
)), .Names = c("id", "rank"), row.names = c(NA, -9L), class = "data.frame")
您可以使用 dplyr
包 :
library(dplyr)
df %>%
group_by(id, rank) %>%
mutate(dg = ifelse(n() > 1, F,T))
这会给你:
# Source: local data frame [6 x 3]
# Groups: id, rank [5]
#
# # A tibble: 6 x 3
# id rank dg
# <dbl> <dbl> <lgl>
# 1 1 1 TRUE
# 2 2 2 TRUE
# 3 2 1 TRUE
# 4 3 3 FALSE
# 5 3 3 FALSE
# 6 4 4 TRUE
注意: 您只需将其转换回data.frame()
。
data.table
解决方案 将是:
dt <- data.table(df)
dt$dg <- ifelse(dt[ , dg := .N, by = list(id, rank)]$dg>1,F,T)
<强> 数据:的强>
df <- structure(list(id = c(1, 2, 2, 3, 3, 4), rank = c(1, 2, 1, 3,
3, 4)), .Names = c("id", "rank"), row.names = c(NA, -6L), class = "data.frame")
# > df
# id rank
# 1 1 1
# 2 2 2
# 3 2 1
# 4 3 3
# 5 3 3
# 6 4 4
<强> ñ。 B。 除非您想要一个不同的标识符而不是TRUE/FALSE
,否则使用ifelse()
是多余的并且计算成本。 @DavidArenburg