【问题标题】:operations (+, -, /, *) on unequal-sized data.table对大小不等的 data.table 进行操作(+、-、/、*)
【发布时间】:2014-07-24 17:29:11
【问题描述】:

1) 是否可以使用data.table 在大小不等的data.tables 之间进行运算(乘法、除法、加法、减法),还是必须使用data.frame 来完成?

以下示例是我原始帖子的简化版本。在我的实际数据集中,它将是 A1:A12、B1:B12、C1:C12、E1:E12、F1:F12 等。我在 J 和 K 列中添加以接近我的原始数据集并表明我不能在矩阵中执行以下操作。

# Sample Data
library(data.table)
input1a <- data.table(ID = c(37, 45, 900), 
              A1 = c(1, 2, 3), 
              A2 = c(43, 320, 390), 
              B1 = c(-0.94, 2.2, -1.223), 
              B2 = c(2.32, 4.54, 7.21), 
              C1 = c(1, 2, 3), 
              C2 = c(-0.94, 2.2, -1.223), 
              D = c(43, 320, 390), 
              J = paste0("measurement_1", 1:3), 
              K = paste0("type_1", 1:3))
setkey(input1a, ID)
input1a
#      ID  A1  A2     B1   B2  C1     C2   D              J       K
#  1:  37   1  43 -0.940 2.32   1 -0.940  43 measurement_11 type_11
#  2:  45   2 320  2.200 4.54   2  2.200 320 measurement_12 type_12
#  3: 900   3 390 -1.223 7.21   3 -1.223 390 measurement_13 type_13

input2a <- data.table(ID = c(37, 45, 900), 
                      E1 = c(23, -0.2, 12), 
                      E2 = c(-0.33, -0.012, -1.342))
setkey(input2a, ID)
input2a
#     ID         E1     E2
# 1:  37 -0.6135756 -0.330
# 2:  45 -0.0124872 -0.012
# 3: 900 -0.4165049 -1.342

outputa <- 0.00066 * input1a[, c(4:5), with = FALSE] *   
input1a[, 8, with = FALSE] * input2a[, c(2:3), with = FALSE] # no keys, but would 
# like to keep the keys
# outputa <- 0.00066 * B1:B2 * D * A1:A2 / referring back to the column names
setnames(outputa, 2:3, c("F1", "F2"))

使用outputa的结果

outputa # using existing code and gives a result with no keys
#            F1             F2
# 1: -0.6135756    -0.02172773
# 2: -0.0929280    -0.01150618
# 3: -3.7776024    -2.49055607

在下面的代码中,我取了outputa,它没有保留密钥,并将outputa重写为outputause。我想回答以下问题,以便我可以对数据集执行所需的操作,同时保持键不变。

2) 如何用为每组列定义的 x 重写以下代码?这个问题源于Weighted sum of variables by groups with data.table,我在尝试用我的数据集复制任何答案时遇到了麻烦。

每组列定义如下:

  • A1:A2 (input1a[, 2:3]),
  • B1:B2 (input1a[, 4:5]) 和
  • Dinput1a[, 8]

outputause 中,如果 input1a[, c(4:5), with = FALSE] 是来自 input1a 的唯一组,那么它就是 x

如果您有多个来自单个data.table 的组,如下所示?

outputause <- input1a[, lapply(.SD, function(x) {
    0.00066 * input1a[, c(4:5), with = FALSE] * input1a[, 8, with = FALSE] * 
      input2a[, c(2, 3), with = FALSE]
  }), by = key(input1a)] # keeping keys intact
setnames(outputause, 2:3, c("F1", "F2"))

使用 outputause 的结果

outputause # using revised code and result includes the keys
#    ID             F1               F2
# 1: 37    -0.6135756       -0.02172773
# 2: 45    -0.0929280       -0.01150618
# 3: 900   -3.7776024       -2.49055607

更新

input2at <- data.table(t(input2a))
inputs <- data.table(input1a, input2at)

我已转置input2a 并将其与data.table inputs 中的input1a 合并。在这个简单的示例中,我有 3 行,但在我的实际数据集中,我将有接近 1300 行。这就是我提出问题 2) 的原因。

谢谢。

【问题讨论】:

  • 我不确定你想在那里做什么,但你为什么要使用data.table呢?你展示的内容最好用矩阵来完成。 PS:请在您的代码中添加一些换行符。水平滚动使阅读变得非常困难。
  • 也许您可以用2x3 表和2x2 表来说明您的问题?并包括您的预期输出?目前情况还很不明朗。
  • @Roland 感谢您的 cmets 和代码修复。我添加了两列文本来说明我为什么使用data.table 而不是matrix。示例中的输出代表我正在使用各种系数、大约 1300 个站点的月度数据(12 列的集合)和特定于位置的数据来求解的最复杂的方程。对于求解的每个方程(大约 15 个),我需要保留作为每个站点标识符的密钥。
  • 恕我直言,您的首要任务应该是摆脱重复的列名。然后你可能应该重塑为长格式并加入 data.tables。
  • 感谢您尝试简化,但“我怎样才能重写此代码 [8 行密集、未注释的代码]”不是一个好问题。请尝试制作一个最小示例,只需一两个操作,您可以尝试自己进行概括。并且不要只是将它添加到底部,编辑您的问题删除所有不必要的细节 - 这太长了,目前无法接近。

标签: r data.table


【解决方案1】:

我正在根据R data.table operations with multiple groups in single data.table and outside function with lapply 中提供给我的答案来回答我自己的问题。

outputa <- data.table(input1a, input2a)
setnames(outputa, 8, "D1")
outputa[, D2 := D1]

fun <- function(B, D, E) 0.00066 * B * D * E

outputa[, lapply(1:2, function(i) fun(get(paste0('B', i)),
                                  get(paste0('D', i)),
                                  get(paste0('E', i)))),
      by = ID]

【讨论】:

    猜你喜欢
    • 2020-06-10
    • 2011-12-14
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 2018-10-01
    • 2013-04-12
    相关资源
    最近更新 更多