刚开始使用R,我需要一些帮助来理解for / nested循环的应用。
StudyID<-c(1:5)
SubjectID<-c(1:5)
df<-data.frame(StudyID=rep(StudyID, each=5), SubjectID=rep(SubjectID, each=1))
如何创建名为ID的新列,该列将使用studyID
和subjectID
的组合来创建唯一ID?
因此,对于此数据,唯一ID应为1:25。
所以最终数据如下所示:
UniqueID<- c(1:25)
df<-cbind(df,UniqueID)
View(df)
还有其他方法可以更快更有效地循环吗?
答案 0 :(得分:2)
使用OBJPROP_PRICE1 & OBJPROP_PRICE2
包,您可以执行以下操作:
dplyr
返回:
library(dplyr)
df$Id = group_indices(df,StudyID,SubjectID)
答案 1 :(得分:2)
在不加载任何库(基础R)的情况下实现这一目标的另一种方法是(假设数据框基于两列进行排序):
StudyID<-c(1:5)
SubjectID<-c(1:5)
df<-data.frame(StudyID=rep(StudyID, each=5), SubjectID=rep(SubjectID, each=1))
df$uniqueID <- cumsum(!duplicated(df[1:2]))
或者你可以使用评论中提到的这个解决方案(我比第一个解决方案更喜欢这个):
df$uniqueID <- as.numeric(factor(do.call(paste, df)))
输出结果为:
> print(df, row.names = FALSE)
#StudyID SubjectID uniqueID
# 1 1 1
# 1 2 2
# 1 3 3
# 1 4 4
# 1 5 5
# 2 1 6
# 2 2 7
# 2 3 8
# 2 4 9
# 2 5 10
# 3 1 11
# 3 2 12
# 3 3 13
# 3 4 14
# 3 5 15
# 4 1 16
# 4 2 17
# 4 3 18
# 4 4 19
# 4 5 20
# 5 1 21
# 5 2 22
# 5 3 23
# 5 4 24
# 5 5 25
答案 2 :(得分:1)
您可以在基地R中找到interaction
:
df$uniqueID <- with(df, as.integer(interaction(StudyID,SubjectID)))
例如(这个例子表达了你所追求的更好):
set.seed(10)
df <- data.frame(StudyID=sample(5,10,replace = T), SubjectID=rep(1:5,times=2))
df$uniqueID <- with(df, as.integer(interaction(StudyID,SubjectID)))
# StudyID SubjectID uniqueID
# 1 3 1 3
# 2 2 2 6
# 3 3 3 11
# 4 4 4 16
# 5 1 5 17
# 6 2 1 2
# 7 2 2 6
# 8 2 3 10
# 9 4 4 16
# 10 3 5 19