for loop&如果函数在R中

时间:2015-09-17 17:13:24

标签: r if-statement for-loop

我在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

请帮帮我......谢谢

3 个答案:

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