如何通过每个列与data.table library的列之和来规范化每个列的值?

如何通过每个列与data.table library的列之和来规范化每个列的值?,r,data.table,R,Data.table,我有一个如下所示的数据表(dt您只希望将此更改应用于数字列,因此必须标识这些列。然后使用lappy。 这将创建一个新的data.table。Chinsoon的答案将通过引用进行更新-这可能更好,具体取决于场景 library(data.table) iris_example <- data.table(iris) numeric_cols <- names(iris)[sapply(iris, is.numeric)] iris_example[, lapply(.SD, fun

我有一个如下所示的数据表(dt您只希望将此更改应用于数字列,因此必须标识这些列。然后使用lappy。 这将创建一个新的data.table。Chinsoon的答案将通过引用进行更新-这可能更好,具体取决于场景

library(data.table)
iris_example <- data.table(iris)

numeric_cols <- names(iris)[sapply(iris, is.numeric)]

iris_example[, lapply(.SD, function(x) x/sum(x)), .SDcols = numeric_cols]

# if you want to update by reference
iris_example[, (numeric_cols) := lapply(.SD, function(x) x/sum(x)), .SDcols = numeric_cols]
库(data.table)

iris_示例您可以使用
get
如下所示:

cols <- paste0("S", 1:4)
dt[, (cols) := lapply(cols, function(x) get(x) / sum(get(x)))]
会话信息:

data.table_1.10.4-3 
R version 3.4.4 (2018-03-15)
Platform: x86_64-w64-mingw32/x64 (64-bit)

我们也可以考虑下面的方法,它也适用于基本的R数据帧。

library(data.table)

# Create example data.table
DT <- fread(
  "chr    gene_id       S1         S2         S3           S4
chr1      a          30         50         70           90
  chr2      b          40         60         80           100
  chr3      c          50         70         90           120
  chr4      d          60         80         100          130"
)

# Use lapply to loop through column 3 to 6
DT[, 3:6] <- lapply(DT[, 3:6], function(x) x/sum(x))

print(DT)
#     chr gene_id        S1        S2        S3        S4
# 1: chr1       a 0.1666667 0.1923077 0.2058824 0.2045455
# 2: chr2       b 0.2222222 0.2307692 0.2352941 0.2272727
# 3: chr3       c 0.2777778 0.2692308 0.2647059 0.2727273
# 4: chr4       d 0.3333333 0.3076923 0.2941176 0.2954545
库(data.table)
#创建示例data.table

DT变化如果你想避免
get
-
DT[,.SD/lapply(.SD,sum),.SDcols=cols]
事实上我更喜欢你的答案。我认为对于大型数据集来说,它会更快。只需在
j
前面添加
(数值):=
即可通过引用进行更改。我会将其添加到
library(data.table) 

DT <- as.data.table(matrix(rnorm(4*1e7), ncol=4))
#DT <- as.data.table(matrix(rnorm(4*1e4), nrow=4))

library(microbenchmark)
microbenchmark(

    DT[, lapply(.SD, function(x) x/sum(x)), .SDcols=names(DT)],

    DT[, .SD / lapply(.SD, sum), .SDcols=names(DT)],

    DT[, lapply(names(DT), function(x) get(x) / sum(get(x)))],

    #if you change ncol to nrow in matrix function above, you will understand why pple always ask you to go long format
    melt(DT)[, value / sum(value), by=variable],#[,
        #lapply(names(DT), function(x) .SD[variable==x, V1])],

    times=3L
)
Unit: milliseconds
                                                         expr       min        lq      mean    median        uq       max neval
 DT[, lapply(.SD, function(x) x/sum(x)), .SDcols = names(DT)]  245.9107  250.3230  278.4220  254.7353  294.6776  334.6200     3
              DT[, .SD/lapply(.SD, sum), .SDcols = names(DT)]  534.5416  540.0630  602.4990  545.5845  636.4777  727.3708     3
      DT[, lapply(names(DT), function(x) get(x)/sum(get(x)))]  248.1819  381.0036  440.7233  513.8254  536.9940  560.1625     3
                  melt(DT)[, value/sum(value), by = variable] 1219.2584 1250.5846 1425.0604 1281.9107 1527.9614 1774.0120     3
data.table_1.10.4-3 
R version 3.4.4 (2018-03-15)
Platform: x86_64-w64-mingw32/x64 (64-bit)
library(data.table)

# Create example data.table
DT <- fread(
  "chr    gene_id       S1         S2         S3           S4
chr1      a          30         50         70           90
  chr2      b          40         60         80           100
  chr3      c          50         70         90           120
  chr4      d          60         80         100          130"
)

# Use lapply to loop through column 3 to 6
DT[, 3:6] <- lapply(DT[, 3:6], function(x) x/sum(x))

print(DT)
#     chr gene_id        S1        S2        S3        S4
# 1: chr1       a 0.1666667 0.1923077 0.2058824 0.2045455
# 2: chr2       b 0.2222222 0.2307692 0.2352941 0.2272727
# 3: chr3       c 0.2777778 0.2692308 0.2647059 0.2727273
# 4: chr4       d 0.3333333 0.3076923 0.2941176 0.2954545