我在R中用if函数编写了一个循环。表格如下:
ID category
1 a
1 b
1 c
2 a
2 b
3 a
3 b
4 a
5 a
我想使用带有if函数的for循环来添加另一列来计算每个分组ID,如下面的count列: ID类别计数
1 a 1
1 b 2
1 c 3
2 a 1
2 b 2
3 a 1
3 b 2
4 a 1
5 a 1
我的代码是(输出是表名):
for (i in 2:nrow(output1)){
if(output1[i,1] == output[i-1,1]){
output1[i,"rn"]<- output1[i-1,"rn"]+1
}
else{
output1[i,"rn"]<-1
}
}
但结果会返回,因为所有计数列值都是&#34; 1&#34;。
ID category Count
1 a 1
1 b 1
1 c 1
2 a 1
2 b 1
3 a 1
3 b 1
4 a 1
5 a 1
请帮帮我......谢谢
答案 0 :(得分:3)
有一些包和矢量化的方法来完成这项任务,但是如果你正在练习循环,请尝试:
output1$rn <- 1
for (i in 2:nrow(output1)){
if(output1[i,1] == output1[i-1,1]){
output1[i,"rn"]<- output1[i-1,"rn"]+1
}
else{
output1[i,"rn"]<-1
}
}
使用原始代码,当您在循环的第三行中调用output1[i-1,"rn"]+1
时,您引用的是第一遍中不存在的行。首先创建行并使用值1
填充它,然后为循环提供明确的引用。
output1
# ID category rn
# 1 1 a 1
# 2 1 b 2
# 3 1 c 3
# 4 2 a 1
# 5 2 b 2
# 6 3 a 1
# 7 3 b 2
# 8 4 a 1
# 9 5 a 1
使用dplyr软件包,您可以快速完成:
library(dplyr)
output1 %>% group_by(ID) %>% mutate(rn = 1:n())
或者使用data.table:
library(data.table)
setDT(output1)[,rn := 1:.N, by=ID]
使用base R
,您还可以使用:
output1$rn <- with(output1, ave(as.character(category), ID, FUN=seq))
在提到的两个软件包上有一些插图和教程,并在R控制台中搜索?ave
以获取最后一种方法。
答案 1 :(得分:1)
循环解决方案将非常缓慢。这是使用data.table的一行解决方案:
require(data.table)
a<-data.table(ID=c(1,1,1,2,2,3,3,4,5),category=c('a','b','c','a','b','a','b','a','a'))
a[,':='(category_count = 1:.N),by=.(ID)]
答案 2 :(得分:1)
你想要的实际上是一系列因子水平。这样做
df$count=as.numeric(df$category)
这将作为
发出 ID category count
1 1 a 1
2 1 b 2
3 1 c 3
4 2 a 1
5 2 b 2
6 3 a 1
7 3 b 2
8 4 a 1
9 5 a 1
如果您的类别已经是一个因素。如果没有先转换为因子
df$category=as.factor(df$category)
df$count=as.numeric(df$category)