【问题标题】:Create list with looping使用循环创建列表
【发布时间】:2014-03-17 10:15:43
【问题描述】:

我有一个 i 次 j (ixj) 虚拟矩阵,用于对公司的事件进行评级,其中包含 i 个日期和 j 个不同的公司。在评分发生的那一天评分为[i,j]=1,否则为 0。

我想创建一个列表,其中包含 4 个子列表(4 家公司各有 1 个)。每个子列表都说明了特定公司的评级事件的行号。

这是我的代码:

r<-list(); i=1;j=2;
for(j in 1:4){
    x<-list()
    for(i in 100){
        if(rating[i,j]!=0){
        x<-c(x,i)
        i=i+1
        }
        else{i=i+1}
    }
    r[[j]]<-x
    j=j+1
}

它不知何故不起作用,我真的不知道错误在哪里。 x 子列表始终为空。有人可以帮忙吗?

非常感谢!

这是一个示例评分矩阵:

 rating<-matrix(data = 0, nrow = (100), ncol = 4, dimnames=list(c(1:100), c(1:4)));
 rating[3,1]=1;rating[7,1]=1;rating[20,1]=1;rating[75,1]=1;
 rating[8,2]=1;rating[40,2]=1;rating[50,2]=1;rating[78,2]=1;
 rating[1,3]=1;rating[4,3]=1;rating[17,3]=1;rating[99,3]=1;
 rating[10,4]=1;rating[20,4]=1;rating[30,4]=1;rating[90,4]=1;

【问题讨论】:

  • 每次在 j-indexed-loop 中遇到 x&lt;-list() 时,x 中的任何先前值都将被删除。您也不应该在 i-indexed-loop 中更改 i。 for-function 会为你做这件事。
  • 您好,感谢您的帮助。我不认为这是错误:我希望 x 子列表被覆盖,因为在第二个 for 循环中,公司 j 的所有评级事件都存储在 x 中。然后我将 x 添加到列表 r,并为公司 j+1 重新开始(所以 x 被覆盖,但这没关系,因为它存储在 r[[j]] 中。
  • 使用dput发布一小部分rating
  • 刚刚做了上面,还调整了该矩阵的代码,所以你可以复制所有内容。谢谢你的帮助!!

标签: r list if-statement for-loop


【解决方案1】:

你可以试试这个:

set.seed(123)
m <- matrix(data = sample(c(0, 1), 16, replace = TRUE), ncol = 4,
            dimnames = list(date = 1:4, company = letters[1:4]))
m
#     company
# date a b c d
#    1 0 1 1 1
#    2 1 0 0 1
#    3 0 1 1 0
#    4 1 1 0 1

lapply(as.data.frame(m), function(x){
  which(x == 1)
})

# $a
# [1] 2 4
# 
# $b
# [1] 1 3 4
# 
# $c
# [1] 1 3
# 
# $d
# [1] 1 2 4

更新
或者更紧凑(感谢@flodel!):

lapply(as.data.frame(m == 1), which)

【讨论】:

  • 完美,非常感谢 Henrik!我应该学会使用函数而不是循环:)
  • 更紧凑:lapply(as.data.frame(m) == 1, which)
  • @flodel,感谢您的评论。我无法使用您的代码获得相同的结果;我得到一个包含 16 个元素的列表,而不是每个公司一个元素。也许我在这里错过了一些明显的东西......
  • 很有趣...然后lapply(as.data.frame(m == 1), which) :-) 抱歉,我在评论之前没有测试。
  • @flodel,我在答案中添加了您的替代方案,以使其更加明显。感谢您的建议!
【解决方案2】:

(留下 for 循环。)如果评级确实是一个矩阵,或者即使它是一个数据框,那么为什么不使用 rowSums:

r <- rowSums(rating) # accomplished the stated task more effectively.

# simple example: 
> rating <- matrix( rbinom(100, 1,prob=.5), 10)
> rating
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1    0    1    0    0    1    1    0    0     1
 [2,]    1    0    0    0    0    0    0    1    1     1
 [3,]    0    0    1    1    1    1    0    0    1     0
 [4,]    1    0    0    0    1    1    0    0    0     1
 [5,]    1    1    0    1    1    1    1    0    0     0
 [6,]    1    1    1    0    1    1    1    0    1     0
 [7,]    0    1    0    1    0    1    1    0    1     0
 [8,]    0    1    0    0    1    1    0    1    1     0
 [9,]    1    1    1    0    1    1    1    1    0     0
[10,]    0    1    0    0    1    0    0    1    0     1
> rowSums(rating)
 [1] 5 4 5 4 6 7 5 5 7 4
> rowSums(as.data.frame(rating))
 [1] 5 4 5 4 6 7 5 5 7 4

如果它需要是一个列表,那么只需将其包装为 as.list() 即可。

【讨论】:

  • 您好,感谢您的帮助,但我需要的是评级发生时的行号,而不是评级事件的数量。
猜你喜欢
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多