对于R中循环中的i

对于R中循环中的i,r,R,我一直在努力掌握一个基本的编程概念——for循环。我通常处理体系结构数据,这样测量会重复使用唯一标识符的级别,如下所示: ID Measure 1 2 1 3 1 3 2 4 2 1 ... 通常,我需要创建一个新列来聚合ID中的数据,或者为ID的每个级别的每一行生成一个值。前者我使用base或dplyr中相当基本的函数,但对于后者,我希望养成为循环创建的习惯 因此,在本例中,我希望在假设的df中添加一列,这样新的列从每个ID的一列开始,并将1添加到后续的每一行,直到出现

我一直在努力掌握一个基本的编程概念——
for
循环。我通常处理体系结构数据,这样测量会重复使用唯一标识符的级别,如下所示:

ID  Measure
1   2
1   3
1   3
2   4
2   1
...
通常,我需要创建一个新列来聚合
ID
中的数据,或者为
ID
的每个级别的每一行生成一个值。前者我使用
base
dplyr
中相当基本的函数,但对于后者,我希望养成为
循环创建
的习惯

因此,在本例中,我希望在假设的
df
中添加一列,这样新的列从每个
ID
的一列开始,并将
1
添加到后续的每一行,直到出现新的
ID

那么这个,

ID  Measure NewVal
1   2       1
1   3       2
1   3       3
2   4       1
2   1       2
...

我很想学习计算方面的
,但如果还有其他方法,我也很想听听。

一种方法是使用
splitstackshape
软件包。有一个函数名为
getanID
。这是你的朋友。如果您的df被称为
mydf
,您将执行以下操作。请注意,结果是data.table。如有必要,您希望将其转换为data.frame

library(splitstackshape)
getanID(mydf, "ID")

#   ID Measure .id
#1:  1       2   1
#2:  1       3   2
#3:  1       3   3
#4:  2       4   1
#5:  2       1   2
数据

mydf <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L), Measure = c(2L, 3L, 
3L, 4L, 1L)), .Names = c("ID", "Measure"), class = "data.frame", row.names = c(NA, 
-5L))

mydf我建议您不要为此使用for循环。这不是一个适合一个人的好地方。如果您愿意,您可以在
plyr
(或
dplyr
)中轻松完成此操作:

require(plyr)
x <- data.frame(cbind(rnorm(100), rnorm(100)))
x$ID <- sample(1:10, 100, replace=T)

new_col <- function(x) {
  x <- x[order(x[,1]), ]
  x$NewVal <- 1:nrow(x)
  return(x)
}

x <- ddply(.data= x, .var= "ID", .fun= new_col)
require(plyr)

x
seq_沿
给出一个从1开始的递增序列,其长度与其输入相同
tapply
用于将功能应用于不同级别的输入。这里我们不关心提供了什么,因此您可以将
ID
列应用于自身:

> d$NewVal <- unlist(tapply(d$ID, d$ID, FUN=seq_along))
> d
  ID Measure NewVal
1  1       2      1
2  1       3      2
3  1       3      3
4  2       4      1
5  2       1      2
>d$NewVal d
ID度量NewVal
1  1       2      1
2  1       3      2
3  1       3      3
4  2       4      1
5  2       1      2

或者您可以使用
ave
。优点是它将以与原始数据集中相同的顺序提供
序列
,这在无序数据集中可能是有益的

transform(df, NewVal=ave(ID, ID, FUN=seq_along))
#  ID Measure NewVal
#1  1       2      1
#2  1       3      2
#3  1       3      3
#4  2       4      1
#5  2       1      2
对于更一般的情况(如果
ID
列为
因子

或者如果订购了
ID

df$NewVal <- sequence(tabulate(df$ID))
数据
df您还可以使用
data.table
通过引用分配序列


做这种工作有很多选择。很高兴看到各种各样的选择。@jazzurro是的,但我喜欢你的方法。它很紧凑。
df$NewVal <- sequence(tabulate(df$ID))
library(dplyr)
 df %>% 
    group_by(ID) %>% 
    mutate(NewVal=row_number())
df <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L), Measure = c(2L, 3L, 
3L, 4L, 1L)), .Names = c("ID", "Measure"), class = "data.frame", 
row.names = c(NA, -5L))
# library(data.table)
setDT(mydf)  ## convert to data table
mydf[,NewVal := seq(.N), by=ID]  ## .N contains number of rows in each ID group

#    ID Measure NewVal
# 1:  1       2      1
# 2:  1       3      2
# 3:  1       3      3
# 4:  2       4      1
# 5:  2       1      2

setDF(mydf)  ## convert easily to data frame if you wish.