【问题标题】:Count previous occurences of a string across multiple columns in R计算 R 中多个列中字符串的先前出现次数
【发布时间】:2015-05-15 00:58:09
【问题描述】:

我有一个带有时间索引的四列矩阵和三列名称(字符串)。这是一些玩具数据:

x = rbind(c(1,"sam","harry","joe"), c(2,"joe","sam","jack"),c(3,"jack","joe","jill"),c(4,"harry","jill","joe"))

我想创建三个额外的向量来计算(对于每一行)任何先前(但不是后续)出现的名称。这是玩具数据的预期结果:

y = rbind(c(0,0,0),c(1,1,0),c(1,2,0),c(1,1,3))

我不知道如何解决这个问题,并在 Stack Overflow 上搜索了相关示例。 dplyr 提供了查找总计数的答案,但(据我所知)不是逐行计算的。

我试图在单列空间中编写一个函数来处理这个问题,但没有运气,即

thing = sapply(x,function(i)length(grep(i,x[x[1:i]])))

任何提示将不胜感激。

【问题讨论】:

  • 您是否真的使用矩阵,或者您的实际数据是否以data.frames 的形式读取?
  • 从您想要的输出中看起来很清楚,这不是“针对每一行”完成的,而是通过“按行”遍历整个矩阵来完成的。 R 矩阵的自然排序是按列排列的,这就是@AnandaMahto 需要使用两次转置操作的原因。

标签: r sapply


【解决方案1】:

这是一个典型的ave + seq_along 类型的问题,但是我们需要先将数据转换成向量:

t(`dim<-`(ave(rep(1, prod(dim(x[, -1]))), 
              c(t(x[, -1])), FUN = seq_along)  - 1, 
          rev(dim(x[, -1]))))
#      [,1] [,2] [,3]
# [1,]    0    0    0
# [2,]    1    1    0
# [3,]    1    2    0
# [4,]    1    1    3

也许更具可读性:

## x without the first column as a vector
x_vec <- c(t(x[, -1]))

## The values that you are looking to obtain...
y_vals <- ave(rep(1, length(x_vec)), x_vec, FUN = seq_along) - 1

## ... in the format you want to obtain them
matrix(y_vals, ncol = ncol(x) - 1, byrow = TRUE)
#      [,1] [,2] [,3]
# [1,]    0    0    0
# [2,]    1    1    0
# [3,]    1    2    0
# [4,]    1    1    3

【讨论】:

    【解决方案2】:

    你可以这样做:

    el = unique(c(x[,-1]))
    val = Reduce(`+`, lapply(el, function(u) {b=c(t(x[,-1]))==u; b[b==T]=(cumsum(b[b==1])-1); b}))
    
    matrix(val, ncol=ncol(x[,-1]), byrow=T)
    #         [,1] [,2] [,3]
    #[1,]    0    0    0
    #[2,]    1    1    0
    #[3,]    1    2    0
    #[4,]    1    1    3
    

    【讨论】:

      猜你喜欢
      • 2013-07-24
      • 2019-06-03
      • 2022-01-06
      • 2021-05-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 2020-03-07
      • 1970-01-01
      相关资源
      最近更新 更多