3

我在 R 中编程,我遇到了以下问题:

我有一个数据字符串 jb,它很长。这是它的一个简单版本:

jb:    a     b     frequency               jb.expanded: a    b   
       5     3        2                                 5    3
       5     7        1                                 5    3
       9     1        40                                5    7
       12    4        5                                 9    1
       12    5        13                                9    1
                                                        ...  ...   

我想复制行,复制的频率是列频率。这意味着,第一行被复制两次,第二行被复制一次,依此类推。我已经用代码解决了这个问题

jb.expanded <- jb[rep(row.names(jb), jb$freqency), 1:2] 

现在问题来了:

每当频率角中的任何数字大于 10 时,重复列的数量都是错误的。例如:

Frequency: 43 --> 14 columns
           40 --> 13 columns
           13 --> 11 columns
           14 --> 12 columns

你能帮助我吗?我不知道如何解决这个问题,我在互联网上也找不到任何东西。

谢谢你的帮助!

4

3 回答 3

6

更新

重新审视这个问题后,我觉得@Codoremifa 的假设是正确的,即您的“频率”列可能是factor.

如果是这种情况,这里有一个例子。它与您的实际数据不匹配,因为我不知道您的数据集中还有哪些其他级别。

mydf$F2 <- factor(as.character(mydf$frequency))
## expandRows(mydf, "F2")
mydf[rep(rownames(mydf), mydf$F2), ]
#      a b frequency F2
# 1    5 3         2  2
# 1.1  5 3         2  2
# 1.2  5 3         2  2
# 2    5 7         1  1
# 3    9 1        40 40
# 3.1  9 1        40 40
# 3.2  9 1        40 40
# 3.3  9 1        40 40
# 4   12 4         5  5
# 4.1 12 4         5  5
# 4.2 12 4         5  5
# 4.3 12 4         5  5
# 4.4 12 4         5  5
# 5   12 5        13 13
# 5.1 12 5        13 13

嗯。对我来说,这看起来不像 61 行。为什么不?因为rep使用基于 的数值factor,在这种情况下与显示的值完全不同:

as.numeric(mydf$F2)
# [1] 3 1 4 5 2

要正确转换它,您需要:

as.numeric(as.character(mydf$F2))
# [1]  2  1 40  5 13

原始答案

不久前,我写了一个函数,它更像是@Simono101 的答案的概括。该函数如下所示:

expandRows <- function(dataset, count, count.is.col = TRUE) {
  if (!isTRUE(count.is.col)) {
    if (length(count) == 1) {
      dataset[rep(rownames(dataset), each = count), ]
    } else {
      if (length(count) != nrow(dataset)) {
        stop("Expand vector does not match number of rows in data.frame")
      }
      dataset[rep(rownames(dataset), count), ]
    }
  } else {
    dataset[rep(rownames(dataset), dataset[[count]]), 
            setdiff(names(dataset), names(dataset[count]))]
  }
}

出于您的目的,您可以使用expandRows(mydf, "frequency")

head(expandRows(mydf, "frequency"))
#     a b
# 1   5 3
# 1.1 5 3
# 2   5 7
# 3   9 1
# 3.1 9 1
# 3.2 9 1   

其他选项是将每一行重复相同的次数:

expandRows(mydf, 2, count.is.col=FALSE)
#      a b frequency
# 1    5 3         2
# 1.1  5 3         2
# 2    5 7         1
# 2.1  5 7         1
# 3    9 1        40
# 3.1  9 1        40
# 4   12 4         5
# 4.1 12 4         5
# 5   12 5        13
# 5.1 12 5        13

或指定每行重复多少次的向量。

expandRows(mydf, c(1, 2, 1, 0, 2), count.is.col=FALSE)
#      a b frequency
# 1    5 3         2
# 2    5 7         1
# 2.1  5 7         1
# 3    9 1        40
# 5   12 5        13
# 5.1 12 5        13

请注意最后两个选项中的必需count.is.col = FALSE参数。

于 2013-10-22T13:50:34.610 回答
3

几乎。您想传递[行索引向量,而不是row.names. 试试这个...

jb[ rep( seq_len( nrow(jb) ) , times = jb$frequency ) , ]

rep( seq_len( nrow(jb) ) , times = jb$frequency ) 
# [1] 1 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
# [39] 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5
于 2013-10-22T13:12:09.500 回答
2

这可能更像是一条评论,但看到所有其他答案都在建议新选项 - 如果您jb$freqency在创建 jb.expanded 时更正拼写,并转换jb$frequency为整数,那么您在问题中提到的构造也有效。

为什么我怀疑 jb$frequency 是一个因素,因为不正确的频率被整齐地排列为 11、12、13、14。

于 2013-10-22T17:08:13.043 回答