【问题标题】:for loop & if function in RR中的for循环和if函数
【发布时间】:2015-09-17 17:13:24
【问题描述】:

我正在用 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
   } 

}

但是返回的结果是所有计数列的值都是“1”。

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

请帮帮我...谢谢

【问题讨论】:

  • 有些函数可以快速完成这个操作,但是用循环练习逻辑控制流总是好的。尝试在循环前添加output1$rn &lt;- 1
  • 尝试按 id 分组并计算行数,library(dplyr); dat %&gt;% group_by(ID) %&gt;% mutate(Count = 1:n())
  • 你只需要基本 R 来执行此操作,请参阅我的答案。

标签: r if-statement for-loop


【解决方案1】:

有一些包和矢量化的方法来完成这项任务,但如果你正在练习循环尝试:

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 以了解最后一种方法。

【讨论】:

  • 从 (v1.9.8) 的下一个版本开始,我们可以简单地这样做:dt[, rn := rowid(ID)]
【解决方案2】:

对于更大的数据,循环解决方案会非常缓慢。这是使用 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)]

【讨论】:

    【解决方案3】:

    你想要的实际上是一个因子级别的列。这样做

    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)
    

    【讨论】:

    • 这只适用于这个特定的例子。如果该类别是一些真实名称,这可能会搞砸,例如as.numeric(factor(c("shoe","bag","tie")))
    • 不明白为什么。它适用于任何因素。即使因子水平是任意长度。
    • 您尝试过我在之前评论中发布的代码吗?
    • 是的..你的意思是它会按字母顺序生成因子水平并分配 shoe=2,bag=1,tie=3?
    • 是的,所以我猜测 OP 可能有不同的类别,可能会产生错误的结果。
    猜你喜欢
    • 2023-04-09
    • 2020-09-25
    • 1970-01-01
    • 2021-07-30
    • 2022-01-10
    • 2018-01-08
    • 2020-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多