r - 在 data.frame 中有效地定位分组常量列

标签 r dataframe plyr

如何从数据框中有效地提取分组常量列?我在下面包含了一个 plyr 实现来准确地说明我想要做什么,但它很慢。我怎样才能尽可能有效地做到这一点? (理想情况下根本不拆分数据框)。

base <- data.frame(group = 1:1000, a = sample(1000), b = sample(1000))
df <- data.frame(
  base[rep(seq_len(nrow(base)), length = 1e6), ], 
  c = runif(1e6), 
  d = runif(1e6)
)


is.constant <- function(x) length(unique(x)) == 1
constant_cols <- function(x) head(Filter(is.constant, x), 1)
system.time(constant <- ddply(df, "group", constant_cols))
#   user  system elapsed 
# 20.531   1.670  22.378 
stopifnot(identical(names(constant), c("group", "a", "b")))
stopifnot(nrow(constant) == 1000)

在我的实际用例中(在 ggplot2 内部)可能有任意数量的常量和非常量列。示例中的数据大小大约是正确的数量级。

最佳答案

(编辑以可能解决具有相同值的连续组的问题)

我暂时提交了这个答案,但我还没有完全说服自己,它会在所有情况下在组常量列中正确识别。但它绝对更快(并且可能会得到改进):

constant_cols1 <- function(df,grp){
    df <- df[order(df[,grp]),]

    #Adjust values based on max diff in data
    rle_group <- rle(df[,grp])
    vec <- rep(rep(c(0,ceiling(diff(range(df)))),
               length.out = length(rle_group$lengths)),
               times = rle_group$lengths)
    m <- matrix(vec,nrow = length(vec),ncol = ncol(df)-1)
    df_new <- df
    df_new[,-1] <- df[,-1] + m

    rles <- lapply(df_new,FUN = rle)
    nms <- names(rles)
    tmp <- sapply(rles[nms != grp],
                  FUN = function(x){identical(x$lengths,rles[[grp]]$lengths)})
    return(tmp)
}

我的基本想法是使用 rle , 明显地。

关于r - 在 data.frame 中有效地定位分组常量列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8647006/

相关文章:

python pandas - 如何将 1 个数据帧中的值映射到另一个数据帧中的索引而不循环?

r - 根据条件比较两个数据帧

r - 如何从 R 中的开始日期和结束日期列表中计算一组中的当前人数

一个 dockerfile 中的 RStudio 和 Shiny

r - color_tile 函数中是否可以使用 2 种以上的颜色?

python - 如何在 Pandas 数据帧上应用具有模式的 bool 过滤器?

python - 如何从多维数据帧创建多条件一维数据帧

r - 通过避免 R 中组中的第一个值来按组计算平均值

r - 与 R 中的日期相关联的条件累积和

使用 R 根据两列重新编码为其余列