在r中使用for / nested循环创建一个新列

时间:2017-05-23 20:26:24

标签: r database for-loop

刚开始使用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的新列,该列将使用studyIDsubjectID的组合来创建唯一ID?

因此,对于此数据,唯一ID应为1:25。

所以最终数据如下所示:

UniqueID<- c(1:25)

df<-cbind(df,UniqueID)

View(df)

还有其他方法可以更快更有效地循环吗?

3 个答案:

答案 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