使用glm的包来读取块中的数据帧。要求所有级别的因子都出现在每个块中。我正在寻找一个很好的策略来重新安排观察,以便最大化每个块中所有值的概率。
示例是
c(4,7,4,4,4,4,4,4,4,4,4,7,4,4,8,8,5,5)
对于大小为8的大小,最佳重排将是
c(4,7,5,8,4,4,4,4,4,4,4,7,4,4,8,8,4,5,8)
是否有一些优雅的方式来改变数据?
刚看到评论......库本身被称为bigglm(它以chunkwise方式读取数据)。载体应该是eqal lenegth。问题实际上只是重新安排大多数块中存在的数据
可以在此处找到数据帧的示例 (https://www.dropbox.com/s/cth8kwcq9ph5j0p/d1.RData?dl=0)
在这种情况下,最重要的是尽可能多的级别存在于尽可能多的块中。块越小,读入时所需的内存就越少。我认为假设10个块是个好点。答案 0 :(得分:1)
我想我明白你要求的是什么,虽然我不熟悉通过块读取数据并使用stringsAsFactors = TRUE
同时假设先验的功能数据(并没有提供叠加因子的其他特征的方法)。我提前提出的建议是,您要么误解了该功能,要么将其误用于您的特定数据问题。
我在这样的问题上很容易出错,所以无论如何我都会尝试解决推断的问题。
您声称该函数将在前8个元素中读取,并在其上进行处理。它必须知道(在这种情况下)有四个因素需要考虑;正如您所问,最简单的方法是在每个块中都存在这些因素。一旦它处理了前8行,它就会读取第2个8个元素。对于样本数据,这不起作用,因为后面的8个元素不包含5。
我稍后会定义略微增加的数据来解决这个问题。
数据中整体唯一值的数量不得大于每个块的大小;
每个因子的出现次数必须至少与要读取的块数一样多;以及
所有块中都包含精确chunksize
个元素(即完整),除了最后一个块将包含1到chunksize
个元素之外;麦角,
最后一个块的元素至少与唯一值一样多。
鉴于这些规则,这里有一些代码。这肯定不是唯一的解决方案,并且对于大型数据集可能表现不佳(我还没有进行过大量的测试)。
myfunc <- function(x, chunksize = 8) {
numChunks <- ceiling(length(x) / chunksize)
uniqx <- unique(x)
lastChunkSize <- chunksize * (1 - numChunks) + length(x)
## check to see if it is mathematically possible
if (length(uniqx) > chunksize)
stop('more factors than can fit in one chunk')
if (any(table(x) < numChunks))
stop('not enough of at least one factor to cover all chunks')
if (lastChunkSize < length(uniqx))
stop('last chunk will not have all factors')
## actually arrange things in one feasible permutation
allIndices <- sapply(uniqx, function(z) which(z == x))
## fill one of each unique x into chunks
chunks <- lapply(1:numChunks, function(i) sapply(allIndices, `[`, i))
remainder <- unlist(sapply(allIndices, tail, n = -3))
remainderCut <- split(remainder, ceiling(seq_along(remainder)/4))
## combine them all together, wary of empty lists
finalIndices <- sapply(1:numChunks,
function(i) {
if (i <= length(remainderCut))
c(chunks[[i]], remainderCut[[i]])
else
chunks[[i]]
})
x[unlist(finalIndices)]
}
在您提供的数据中,您有18个元素需要三个块。您的数据将在两个帐户上失败:三个元素只出现两次,因此第三个块肯定不会包含所有元素;而你的最后一个块只有两个元素,不能包含四个元素。
我将增加您的数据以满足两个未命中,并使用:
dat3 <- c(4,7,5,7,8,4,4,4,4,4,4,7,4,4,8,8,5,5,5,5)
如果除了最后一个块之外没有其他原因,它将无法正常调整。
解决方案:
myfunc(dat3, chunksize = 8)
## [1] 4 7 5 8 4 4 4 4 4 7 5 8 4 4 5 5 4 7 5 8
(为了便于检查,将空格添加到输出中)。每个块都有4, 7, 5, 8
作为其前四个元素,因此每个块都包含所有因素。
快速演练(使用debug(myfunc)
),假设x = dat3
和chunksize = 8
。跳下代码:
## Browse[2]> uniqx
## [1] 4 7 5 8
## Browse[2]> allIndices
## [[1]]
## [1] 1 6 7 8 9 10 11 13 14
## [[2]]
## [1] 2 4 12
## [[3]]
## [1] 3 17 18 19 20
## [[4]]
## [1] 5 15 16
这显示了每个唯一元素的索引。例如,有4个位于索引1,6,7等
## Browse[2]> chunks
## [[1]]
## [1] 1 2 3 5
## [[2]]
## [1] 6 4 17 15
## [[3]]
## [1] 7 12 18 16
要填充三个块,此列表开始形成这些块。在这个例子中,我们在第一个块中放置了索引1,2,3和5。回顾allIndices
,您会看到这些代表uniqx
中每个的第一个实例,因此第一个块现在包含c(4, 7, 5, 8)
,其他两个块也是如此。
此时,我们已经满足了在每个块中找到每个唯一元素的基本要求。其余的代码填充了剩余的元素。
## Browse[2]> remainder
## [1] 8 9 10 11 13 14 19 20
这些是到目前为止未已添加到块中的所有索引。
## Browse[2]> remainderCut
## $`1`
## [1] 8 9 10 11
## $`2`
## [1] 13 14 19 20
虽然我们有三个块,但我们这里只有两个列表。这很好,我们没有(并且不需要任何东西)添加到最后一个块。然后,我们将这些与chunks
压缩合并,以形成索引列表列表。 (注意:您可能会尝试mapply(function(a, b) c(a, b), chunks, remainderCut)
,但您可能会注意到如果remainderCut
与chunks
的大小不同,正如我们在此处看到的那样,则其值会被回收。试试吧。)
## Browse[2]> finalIndices
## [[1]]
## [1] 1 2 3 5 8 9 10 11
## [[2]]
## [1] 6 4 17 15 13 14 19 20
## [[3]]
## [1] 7 12 18 16
请记住,每个数字代表x
(原dat3
)内的索引。然后我们unlist
这个分割向量并将索引应用于数据。