我有一个列表,每个元素都是一个字符向量,长度不同。我想将数据绑定为行,这样列名就“对齐”,如果有额外的数据,就创建列,如果缺少数据,就创建NAs
下面是我正在使用的数据的模拟示例
x <- list()
x[[1]] <- letters[seq(2,20,by=2)]
names(x[[1]]) <- LETTERS[c(1:length(x[[1]]))]
x[[2]] <- letters[seq(3,20, by=3)]
names(x[[2]]) <- LETTERS[seq(3,20, by=3)]
x[[3]] <- letters[seq(4,20, by=4)]
names(x[[3]]) <- LETTERS[seq(4,20, by=4)]
如果我确定每个元素的格式是相同的,下面的行通常是我会做的...
do.call(rbind,x)
我希望有人能想出一个很好的解决方案,匹配列名,并用NA
s填空,同时添加新列,如果在绑定过程中发现新列。。。
这是一个使用包data.table
的版本,对于非常大的数据要快一点。它使用函数rbindlist
及其参数填充=TRUE
传递给函数do.call
。
library(data.table)
x <- list()
x[[1]] <- letters[seq(2,20,by=2)]
names(x[[1]]) <- LETTERS[c(1:length(x[[1]]))]
x[[2]] <- letters[seq(3,20, by=3)]
names(x[[2]]) <- LETTERS[seq(3,20, by=3)]
x[[3]] <- letters[seq(4,20, by=4)]
names(x[[3]]) <- LETTERS[seq(4,20, by=4)]
x2 <- lapply(x, as.list)
rbindlist(x2, fill=TRUE)
#> A B C D E F G H I J L O R P T
#> 1: b d f h j l n p r t <NA> <NA> <NA> <NA> <NA>
#> 2: <NA> <NA> c <NA> <NA> f <NA> <NA> i <NA> l o r <NA> <NA>
#> 3: <NA> <NA> <NA> d <NA> <NA> <NA> h <NA> <NA> l <NA> <NA> p t
它增加了一个小的开销,因为它需要用as.list
转换字符向量。这段话还可以为进程增加时间,具体取决于数据的生成方式。
另一方面,它似乎在大型数据集上执行得更快。
它返回一个data.table
。
我重写了@Arun和@GSee的例子,以生成更大的样本。
# generate some huge random data:
set.seed(45)
sample.fun <- function() {
nam <- sample(LETTERS, sample(5:15))
val <- sample(letters, length(nam))
setNames(val, nam)
}
l1 <- replicate(1e6, sample.fun()) # Arun's data, just bigger
l2 <- lapply(l1, as.list) # same data converted with as.list
library(microbenchmark)
library(data.table)
# Arun's function
rbind.named.fill <- function(x) {
nam <- sapply(x, names)
unam <- unique(unlist(nam))
len <- sapply(x, length)
out <- vector("list", length(len))
for (i in seq_along(len)) {
out[[i]] <- unname(x[[i]])[match(unam, nam[[i]])]
}
setNames(as.data.frame(do.call(rbind, out), stringsAsFactors=FALSE), unam)
}
# GSee's function
foo <- function (...)
{
dargs <- list(...)
all.names <- unique(names(unlist(dargs)))
out <- do.call(rbind, lapply(dargs, `[`, all.names))
colnames(out) <- all.names
as.data.frame(out, stringsAsFactors=FALSE)
}
microbenchmark(t1 <- rbind.named.fill(l1),
t2 <- rbindlist(l2, fill=TRUE),
t3 <- do.call(foo, l1),
times=10)
#> Unit: seconds
#> expr min lq mean median uq max neval
#> t1 <- rbind.named.fill(l1) 6.536782 7.545538 9.118771 9.304844 10.505814 11.28260 10
#> t2 <- rbindlist(l2, fill=TRUE) 5.250387 5.787712 6.910340 6.226065 7.579503 10.40524 10
#> t3 <- do.call(foo, l1) 9.590615 11.043557 13.504694 12.550535 15.364464 19.95877 10
identical(t1, data.frame(t2))
#> [1] TRUE
identical(t3, data.frame(t2))
#> [1] TRUE
由reprex包(v0.3.0)创建于2019-08-01
如果你想得到一个矩阵。。。
我最近为一个想要将向量绑定到矩阵中的同事编写了这个函数。
foo <- function (...)
{
dargs <- list(...)
if (!all(vapply(dargs, is.vector, TRUE)))
stop("all inputs must be vectors")
if (!all(vapply(dargs, function(x) !is.null(names(x)), TRUE)))
stop("all input vectors must be named.")
all.names <- unique(names(unlist(dargs)))
out <- do.call(rbind, lapply(dargs, `[`, all.names))
colnames(out) <- all.names
out
}
R > do.call(foo, x)
A B C D E F G H I J L O R P T
[1,] "b" "d" "f" "h" "j" "l" "n" "p" "r" "t" NA NA NA NA NA
[2,] NA NA "c" NA NA "f" NA NA "i" NA "l" "o" "r" NA NA
[3,] NA NA NA "d" NA NA NA "h" NA NA "l" NA NA "p" "t"
rbind.fill
是一个很棒的函数,在data.frames.列表上做得非常好但是恕我直言,对于这种情况,当列表只包含(命名)向量时,它可以做得更快。
require(plyr)
rbind.fill(lapply(x,function(y){as.data.frame(t(y),stringsAsFactors=FALSE)}))
rbind.named.fill <- function(x) {
nam <- sapply(x, names)
unam <- unique(unlist(nam))
len <- sapply(x, length)
out <- vector("list", length(len))
for (i in seq_along(len)) {
out[[i]] <- unname(x[[i]])[match(unam, nam[[i]])]
}
setNames(as.data.frame(do.call(rbind, out), stringsAsFactors=FALSE), unam)
}
基本上,我们得到了所有唯一的名称,以形成最终数据的列。框架然后,我们用length=input创建一个列表,并用NA
填充其余的值。这可能是最“棘手”的部分,因为我们必须在填写NA时匹配名称。然后,我们最后为列设置一次名称(如果需要,也可以使用data.table
package中的setnames
通过引用来设置)。
现在来看一些基准测试:
# generate some huge random data:
set.seed(45)
sample.fun <- function() {
nam <- sample(LETTERS, sample(5:15))
val <- sample(letters, length(nam))
setNames(val, nam)
}
ll <- replicate(1e4, sample.fun())
# plyr's rbind.fill version:
rbind.fill.plyr <- function(x) {
rbind.fill(lapply(x,function(y){as.data.frame(t(y),stringsAsFactors=FALSE)}))
}
rbind.named.fill <- function(x) {
nam <- sapply(x, names)
unam <- unique(unlist(nam))
len <- sapply(x, length)
out <- vector("list", length(len))
for (i in seq_along(len)) {
out[[i]] <- unname(x[[i]])[match(unam, nam[[i]])]
}
setNames(as.data.frame(do.call(rbind, out), stringsAsFactors=FALSE), unam)
}
foo <- function (...)
{
dargs <- list(...)
all.names <- unique(names(unlist(dargs)))
out <- do.call(rbind, lapply(dargs, `[`, all.names))
colnames(out) <- all.names
as.data.frame(out, stringsAsFactors=FALSE)
}
require(microbenchmark)
microbenchmark(t1 <- rbind.named.fill(ll),
t2 <- rbind.fill.plyr(ll),
t3 <- do.call(foo, ll), times=10)
identical(t1, t2) # TRUE
identical(t1, t3) # TRUE
Unit: milliseconds
expr min lq median uq max neval
t1 <- rbind.named.fill(ll) 243.0754 258.4653 307.2575 359.4332 385.6287 10
t2 <- rbind.fill.plyr(ll) 16808.3334 17139.3068 17648.1882 17890.9384 18220.2534 10
t3 <- do.call(foo, ll) 188.5139 204.2514 229.0074 339.6309 359.4995 10
0.1-0.2:********** 0.2-0.3:******** 0.3-0.4:********* 0.5-0.6:********* 0.6-0.7:********* 0.7-0.8:********* 0.4-0.5:********* 0.5-0.6:********* 0.6-0.7:********* 0.1-0.2:********* 0.2-0.3:********* 0.
问题内容: 我试图识别/创建一个函数(在Java中),该函数给我一个非均匀的分布式数字序列。如果我有一个函数说它将给我一个从到的随机数。 该函数最适合任何给定的函数,下面仅是我想要的示例。 但是,如果我们说函数将返回来自分布式的s nonuni。 我想例如说 约占所有案件的20%。 大约是所有情况的50%。 约占所有案件的20%。 大约是所有情况的10。 总之somting,给我一个数字,如正态分
我们在AWS上运行16个节点kafka集群,每个节点是m4. xLargeEC2实例,具有2TB EBS(ST1)磁盘。Kafka版本0.10.1.0,目前我们有大约100个主题。一些繁忙的话题每天会有大约20亿个事件,一些低量的话题每天只有数千个。 我们的大多数主题在生成消息时使用UUID作为分区键,因此分区分布相当均匀。 我们有相当多的消费者使用消费群体从这个集群消费。每个使用者都有一个唯一的
我经常会发现这样的问题:人们最终得到了一个未命名字符向量的未命名列表,并且希望将它们按行绑定到中。这里有一个例子: 一种典型的方法是从基R使用。 然而,这似乎是更多的步骤比它需要的。 因此,我的问题是什么是一种有效的或方法来将未命名字符向量的未命名列表按行绑定到中?
我正在使用一个数据集,其中包含与相结合的度量值,例如: 我试图检测和删除可能出现的潜在峰值,如度量值。 到目前为止,我发现了一些东西: > 这个数据集的时间间隔从15秒一直到25分钟,这使得它非常不均匀 峰的宽度无法事先确定 峰值高度与其他值明显偏离 时间步长的标准化只应在去除异常值后进行,因为它们会干扰结果 由于其他异常(例如,负值、平线),即使没有这些异常,也“不可能”使其变得均匀,因为峰值会
问题内容: 我知道如果我使用Java的Random生成器,并使用nextInt生成数字,则数字将均匀分布。但是,如果我使用2个Random实例,并使用两个Random类生成数字,会发生什么。数字是否会均匀分布? 问题答案: 每个实例生成的数字将均匀分布,因此,如果将两个实例生成的随机数序列组合在一起,则它们也应均匀分布。 请注意,即使结果分布是均匀的,您也可能要注意种子,以避免两个生成器的输出之间