【问题标题】:R for loop through vectors, if subscript out of bounds change to certain valueR for循环遍历向量,如果下标超出范围更改为某个值
【发布时间】:2020-07-12 19:39:20
【问题描述】:

我有一个向量列表,有时值的范围是 1 到 7,有时是 1 到 5。我想遍历它们并使用函数 table 获取频率计数,然后将这些值放入数据框中,但我收到subscript out of bounds 错误。它这样做是因为它需要一个integer 值。发生这种情况时,我想将整数值设置为 0。

是否有一个简单的函数可以环绕integervalue,例如somefunction(t[[6]]) 返回 0?

#list of vectors, the first has values 1 to 7, the second has 1 to 5, 
#the third is 1 to 7 again and is only included to show that my real problem has many
# more vectors to evaluate


vectors<-list(c(1,1,2,2,3,3,3,4,4,5,5,5,6,6,6,6,7,7,7,7,7),
c(1,1,2,2,3,3,3,4,4,5,5,5,5,5,5,5,5,5,5,5,5),
c(1,1,2,2,3,3,3,4,4,5,5,5,6,6,6,6,7,7,7,7,7))

#empty data frame
df<-data.frame()
#loop through list of vectors and get frequncy count per list
for (i in 1:length(vectors)) {
  #count frquency of each value as variable t
  t<-table(vectors[[i]])
      #put frequency count of each value in the data frame - the problem is 
      #that in the second vector, there are only values of 1 to 5, so t[[6]] 
      #reports "subscript out of bounds". I want to change this to a value of 0
  df<-rbind(df,cbind(t[[1]],t[[2]],t[[3]],t[[4]],t[[5]],t[[6]],t[[7]]))
}

df

【问题讨论】:

    标签: r for-loop integer


    【解决方案1】:

    我们可以在设置list的名称后,将list转换为两列data.framestack,而不是循环,然后应用table

    table(stack(setNames(vectors, seq_along(vectors)))[2:1])
    #  values
    #ind  1  2  3  4  5  6  7
    #  1  2  2  3  2  3  4  5
    #  2  2  2  3  2 12  0  0
    #  3  2  2  3  2  3  4  5
    

    上面将是一个table 对象。如果我们需要转换为data.frame(不重新整形为'long'格式)

    as.data.frame.matrix(table(stack(setNames(vectors, seq_along(vectors)))[2:1]))
    

    在这里,我们只应用一次table,因为它会自动找到唯一值,因此效率更高且更简单。如果我们在循环,那么我们必须事先找到唯一值以添加缺失的级别以计为 0


    通过循环,我们可以将单个list 元素转换为factor,并将levels 指定为所有元素的unique

    un1 <- sort(unique(unlist(vectors)))
    t(sapply(vectors, function(x) table(factor(x, levels = un1))))
    

    for 循环中,我们可以使用rbind,但对于rbind,它会期望列名相同或长度相同。所以,不是rbind,一个选项是bind_rows from dplyr

    library(dplyr)
    df <- data.frame()
    for(i in seq_along(vectors)) {
          tbl1 <- table(vectors[[i]])
          df <- bind_rows(df, tbl1)
     }
    

    默认情况下,bind_rowsNA 填充未找到的列。然后我们将NA替换为0

    df[is.na(df)] <- 0
    

    但是,这不是一个有效的选择,就像调用一次 table 所显示的那样

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 2016-01-18
      相关资源
      最近更新 更多