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

0ve6wy6x  于 2023-04-03  发布在  其他
关注(0)|答案(3)|浏览(119)

刚开始使用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)

有没有比循环更快更有效的方法?

6l7fqoea

6l7fqoea1#

使用dplyr包,您可以执行以下操作:

library(dplyr)
df$Id = group_indices(df,StudyID,SubjectID)

这将返回:

#StudyID   SubjectID   Id
#   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         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
vwkv1x7d

vwkv1x7d2#

另一种无需加载任何库(base R)即可实现的方法是(假设 Dataframe 基于两列进行排序):

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
3phpmpom

3phpmpom3#

你可以把interaction写成R进制:

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

相关问题