相关疑难解决方法(0)

data.table join然后将列添加到现有data.frame而不重新复制

我有两个data.tables,X(3米行乘500列)和Y(100行乘两列).

set.seed(1)
X <- data.table( a=letters, b=letters, c=letters, g=sample(c(1:5,7),length(letters),replace=TRUE), key="g" )
Y <- data.table( z=runif(6), g=1:6, key="g" )
Run Code Online (Sandbox Code Playgroud)

我想在X上做一个左外连接,我可以做到Y[X]这一点,感谢:

为什么X [Y]连接data.tables不允许完全外连接或左连接?

但我想在X 复制的情况下添加新列X(因为它很大).

显然,像X <- Y[X]作品这样的东西,但除非data.table比我给它的功劳更加明确(并且我非常狡猾地给予它赞美!),我相信这复制了整个X.

X[ , z:= Y[X,z]$z ] 虽然工作正常,但却不能很好地扩展到多个列.

如何将合并的结果以有效的方式(在副本方面和程序员时间方面)存储回保留的data.table中?

join copy r reference data.table

19
推荐指数
2
解决办法
4154
查看次数

在`data.table`中的`j`表达式中评估列名和目标值

考虑

target <- "vs"
value <- 1

library(data.table)
dt <- as.data.table(head(mtcars))
Run Code Online (Sandbox Code Playgroud)

所以我试图将列名和值作为变量传递到环境中的j表达式中data.table,这相当于

dt[, vs == 1]
# [1] FALSE FALSE  TRUE  TRUE FALSE  TRUE
Run Code Online (Sandbox Code Playgroud)

如果只有值是变量,它可以很好地工作

dt[, vs == value]
# [1] FALSE FALSE  TRUE  TRUE FALSE  TRUE
Run Code Online (Sandbox Code Playgroud)

当它是变量时,我们也可以在data.table范围内调用该列

dt[, target, with = FALSE]
#    vs
# 1:  0
# 2:  0
# 3:  1
# 4:  1
# 5:  0
# 6:  1
Run Code Online (Sandbox Code Playgroud)

但我无法想象如何以简单的方式将两者结合起来

注意:我很清楚我可以做到:

dt[[target]] == value
# [1] FALSE FALSE  TRUE  TRUE FALSE …
Run Code Online (Sandbox Code Playgroud)

r data.table

9
推荐指数
1
解决办法
768
查看次数

r data.table函数式编程/元编程/计算语言

我正在探索使用data.table包装聚合函数(但实际上它可以是任何类型的函数)的不同方法(也提供了一个dplyr示例)并且想知道关于函数式编程/元编程的最佳实践

  • 性能(实现是否与data.table可能适用的潜在优化有关)
  • 可读性(有一个共同商定的标准,例如在大多数使用data.table的包中)
  • 易于推广(元编程是否具有"推广性"的方式存在差异)

基本应用是灵活地聚合表,即参数化变量以聚合,聚合的维度,两者的相应结果变量名称和聚合函数.我已经在三个data.table和一个dplyr方式中实现了(几乎)相同的功能:

  1. fn_dt_agg1(这里我无法弄清楚如何参数化聚合函数)
  2. fn_dt_agg2(由@jangorecki的回答启发这里,他称之为'上的语言计算’)
  3. fn_dt_agg3(灵感来自@Arun的答案,这似乎是元编程的另一种方法)
  4. fn_df_agg1(我在dplyr中的谦虚态度)

图书馆

library(data.table)
library(dplyr)
Run Code Online (Sandbox Code Playgroud)

数据

n_size <- 1*10^6
sample_metrics <- sample(seq(from = 1, to = 100, by = 1), n_size, rep = T)
sample_dimensions <- sample(letters[10:12], n_size, rep = T)
df <- 
  data.frame(
    a = sample_metrics,
    b = sample_metrics,
    c = sample_dimensions,
    d = sample_dimensions,
    x = sample_metrics,
    y = sample_dimensions,
    stringsAsFactors = F)

dt <- as.data.table(df)
Run Code Online (Sandbox Code Playgroud)

实现

1. fn_dt_agg1

fn_dt_agg1 <- 
  function(dt, metric, metric_name, dimension, dimension_name) { …
Run Code Online (Sandbox Code Playgroud)

functional-programming r metaprogramming dplyr data.table

6
推荐指数
1
解决办法
704
查看次数

快速data.table从查找分组多列

我已经搜索了规范的方法来做我正在尝试的东西,但我似乎没有运气得到快速和优雅的工作.简而言之,我有一个包含多个值列的大表,并希望将每个值乘以查找表中的相应因子.我无法弄清楚如何动态传递我想要的列乘以查找值,或者如何在基本表达式之外引用查询值.

这是我的例子,我设置了300万行,有10个值列,这不需要太长时间,并且有点代表数据大小(这将作为更大的循环的一部分实现,因此强调关于表现).我们的value_1:value_10列还有一个包含6个级别和一些匹配乘数的查找表.

library(data.table)

setsize <- 3000000
value_num <- 10
factors <- c("factor_a", "factor_b", "factor_c", "factor_d", "factor_e", "factor_f")
random <- data.table(replicate(10, sample(factors, size = setsize,  replace = T))
                     , replicate(10, rnorm(setsize, mean = 700, sd = 50)))
lookup <- data.table("V1" = factors, replicate(10, seq(.90, 1.5, length.out = length(factors))))
wps <- paste("value", c(1:10), sep = "_")
names(random)[11:20] <- wps
names(lookup)[2:11] <- wps
setkeyv(random, "V1")
setkeyv(lookup, "V1")
Run Code Online (Sandbox Code Playgroud)

解决方案1:它相当快,但我无法弄清楚如何一般地引用i-columns,i.value_1因此我可以将它们传递到循环中或更好地同时应用它们.

f <- function() {
  random[lookup, value_1 := value_1 * i.value_1, by = .EACHI] …
Run Code Online (Sandbox Code Playgroud)

r data.table

5
推荐指数
1
解决办法
241
查看次数

R 数据合并而不复制

在 data.table 中,可以直接处理当前数据表(比如 DT)而无需创建它的副本。例如,这可以在创建新列时完成。

DT[,new_col:=1]
Run Code Online (Sandbox Code Playgroud)

我想知道如何进行合并,特别是左连接。比如左连接的数据表方式是

DT_right[DT_left,on="id"]
Run Code Online (Sandbox Code Playgroud)

但是,这不会修改原始的 DT_left 表,需要我重新分配。IE

DT_left = DT_right[DT_left,on="id"]
Run Code Online (Sandbox Code Playgroud)

有没有办法让我在不重新分配的情况下做到这一点?即直接在 DT_left 上工作。

r data.table

3
推荐指数
1
解决办法
442
查看次数

从另一个数据帧更新数据帧行和列的子集

df1 <- data.frame(w = 1:4, x = c("a", "b", "b", "c"), y = NA)
df1$y[df1$x == "c"] = 1
df2 <- data.frame(x = c("a", "b"), y = 1:2, z = 3:4)
Run Code Online (Sandbox Code Playgroud)

我想用df2中的值更新df1以匹配行,包括所有df2列.

预期结果:

df1
  w x  y  z
1 1 a  1  3
2 2 b  2  4
3 3 b  2  4
4 4 c  1 NA
Run Code Online (Sandbox Code Playgroud)

这是我的尝试:

# add missing columns from df2 to df1
df1[setdiff(colnames(df2), colnames(df1))] <- NA
# update values in df1 from df2 for matching …
Run Code Online (Sandbox Code Playgroud)

r

2
推荐指数
1
解决办法
511
查看次数