我在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
你能帮帮我吗?我不知道如何解决这个问题,我也无法在互联网上找到任何东西。
感谢您的帮助!
答案 0 :(得分:5)
在重新审视这个问题时,我觉得@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
参数。
答案 1 :(得分: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
答案 2 :(得分:1)
这可能更像是评论,但看到所有其他答案都在建议新选项 - 如果在创建jb.expanded时更正jb$freqency
的拼写,并将jb$frequency
转换为整数你在问题中提到的结构也有效。
为什么我怀疑jb $频率是一个因素,因为不正确的频率整齐排序为11,12,13,14。