簡體   English   中英

R函數將計算出的3列寫入數據表

[英]R Function to write 3 calculated columns to a data.table

這可能已經回答了,但是找不到我要找的答案。 我正在嘗試將計算3個變量的函數的輸出寫入data.table。

目前,我將函數復制三次(具有三個不同的名稱),每次都返回一個不同的變量。 它運行三次會花費更多時間。 我了解使用list或某些唯一的data.table命令可能會有更好的方法。

我將不勝感激您可以提供任何輸入來簡化此操作。 以下是我如何一次將其稱為一個變量的示例。

  fn_1 <- function(a, b, c, d){

    for (i in 1:b) { col_1[i] = calculation }
    for (i in 1:c) { col_2[i] = calculation }
    for (i in 1:d) { col_3[i] = calculation }

    return(col_1)
  }

  data[ ,column_1 := fn_1(a,b,c,d) ,by= .(e,f) ]


  fn_2 <- function(a, b, c, d){

    for (i in 1:b) { col_1[i] = calculation }
    for (i in 1:c) { col_2[i] = calculation }
    for (i in 1:d) { col_3[i] = calculation }

    return(col_2)
  }

  data[ ,column_2 := fn_2(a,b,c,d) ,by= .(e,f) ]

OP用data.table標記了問題。 docendo discimus的評論表明了發展的方向。

創建樣本數據

library(data.table)   # CRAN version 1.10.4 used

n <- 10L
DT <- data.table(
  a = 1:n, b = (n:1)^2, c = -(1:n), d = 2 * (1:n) - n/2,
  e = rep(LETTERS[1:2], length.out = n), 
  f = rep(LETTERS[3:4], each = n/2, length.out = n))
DT  
#     a   b   c  d e f
# 1:  1 100  -1 -3 A C
# 2:  2  81  -2 -1 B C
# 3:  3  64  -3  1 A C
# 4:  4  49  -4  3 B C
# 5:  5  36  -5  5 A C
# 6:  6  25  -6  7 B D
# 7:  7  16  -7  9 A D
# 8:  8   9  -8 11 B D
# 9:  9   4  -9 13 A D
#10: 10   1 -10 15 B D

定義功能

fn <- function(p, q, r, s) {
  list(X1 = p + mean(q) + r + s,
       Y2 = p * q + r * s,
       Z3 = p * q - r * s)
}

該函數采用4個參數,並返回3個命名向量的列表。 請注意,與OP的方法相比,函數內部的計算不需要for循環。

將函數應用於data.table

請注意,應用該功能時,OP希望在ef列上分組。

第一個變體創建一個新的data.table。 默認情況下,使用fn中定義的列表元素的名稱:

DT[, fn(a, b, c, d), .(e, f)]
#    e f       X1   Y2  Z3
# 1: A C 63.66667  103  97
# 2: A C 67.66667  189 195
# 3: A C 71.66667  155 205
# 4: B C 64.00000  164 160
# 5: B C 68.00000  184 208
# 6: B D 18.66667  108 192
# 7: B D 22.66667  -16 160
# 8: B D 26.66667 -140 160
# 9: A D 19.00000   49 175
#10: A D 23.00000  -81 153

第二個變體通過引用更新DT 明確說明了新列的名稱。

DT[, c("x", "y", "z") := fn(a, b, c, d), .(e, f)]

DT
#     a   b   c  d e f        x    y   z
# 1:  1 100  -1 -3 A C 63.66667  103  97
# 2:  2  81  -2 -1 B C 64.00000  164 160
# 3:  3  64  -3  1 A C 67.66667  189 195
# 4:  4  49  -4  3 B C 68.00000  184 208
# 5:  5  36  -5  5 A C 71.66667  155 205
# 6:  6  25  -6  7 B D 18.66667  108 192
# 7:  7  16  -7  9 A D 19.00000   49 175
# 8:  8   9  -8 11 B D 22.66667  -16 160
# 9:  9   4  -9 13 A D 23.00000  -81 153
#10: 10   1 -10 15 B D 26.66667 -140 160

你在地獄第二圈 要解決此問題,請預先分配要添加的內容。

data <- data.table(c(1, 2, 3), c(4, 5, 6), c(7, 8, 9))

然后,使用向量化函數進行計算,該計算返回整列要追加的內容。

calculation <- Vectorize(function(x) mean(c(x, 3)))

根據此新函數編寫fn,並返回要添加的整個列塊,然后將其與data綁定以一次添加所有列。 每次都執行所有計算,然后只返回一部分,這是非常慢的。

fn <- function(b, c, d) {
  toBeAdded <- data.table(matrix(nrow = nrow(data), ncol = 3))
  toBeAdded[ , 1] <- calculation(b)
  toBeAdded[ , 2] <- calculation(b)
  toBeAdded[ , 3] <- calculation(b)
  toBeAdded
}

data <- cbind(data, fn(data[1,], data[2,], data[3,]))

根據@docendodiscimus和@ConCave的輸入,回答我自己的問題,我就這樣解決了。 感謝大家的投入!

  fn_1 <- function(a, b, c, d){

    for (i in 1:b) { col_1[i] = calculation }
    for (i in 1:c) { col_2[i] = calculation }
    for (i in 1:d) { col_3[i] = calculation }

      df = data.table(col_1, col_2, col_3)
      return(df)
  }

  data[,c("column_1","column_2","column_3"):= fn_1(a,b,c,d) ,by= .(e,f)]

它必須是一個data.table嗎? 如果不是,那么您可以在dplyr使用mutate

a <- c(1,2,2,1,2,3,4,2)
b <- c(3,3,2,3,5,4,3,2)
c <- c(9,9,8,7,8,9,8,7)
d <- c(0,1,1,0,1,1,0,1)

have <- data.frame(a,b,c,d)

want <- 
  have %>% 
  mutate(abc = a+ b + c,
         db = d * b,
         aa = 2 * a)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM