根据条件

时间:2017-03-10 14:24:44

标签: r data.table lapply

我有一个很大的data.table,有数百列和数千行。大多数列都包含数值,如X / Y或Y / Z等。

我需要翻转这些比率的一些,以便它们从Y / Z转换 - > Z /年。我对这些列的唯一指标是列名,其中包括子串" x / y"或" y / z"。

我可以获得匹配" y / z"的列。使用grepl,但我不确定如何使用apply / lapply等的逻辑值数组。我意识到我可以提取列(通过逻辑索引或{{1转换它们,但我不想丢弃/忽略剩余的列。

最后,我尝试过这样的事情

.SDcols

但是flipcols <- grepl("Y/Z", names(sites)) sites.new <- sites[, , lapply(.SD, function(x) 1/x), .SDcols = flipcols] sites之间没有区别,应该转换的列不会被转换,相应列之间的总和差异为0.

建议?

编辑:关注@ akrun后,我尝试了:=运算符,但它会导致其他问题如下:

sites.new

EDIT2:这是一个最小的例子,目标是转换匹配&#34; Y / Z&#34;的列。模式(这里我们的最小例子中的第二个和第四个),保持其他列不变并且是结果的一部分。

# I think this fails because flipcols is a logical vector and not a list of names or indices
> sites.new <- sites[, (flipcols) := lapply(.SD, function(x) 1/x), .SDcols = flipcols]
Error in `[.data.table`(sites, , `:=`((flipcols), lapply(.SD, function(x) 1/x)),  : 
  LHS of := isn't column names ('character') or positions ('integer' or 'numeric')


# and this seems to fail because .SDcols seems to lock the data in read-only mode
> sites.new <- sites[, which(flipcols) := lapply(.SD, function(x) 1/x), .SDcols = flipcols]
Error in assign(ii, SDenv$.SDall[[ii]], SDenv) : 
  cannot change value of locked binding for '.SD'

1 个答案:

答案 0 :(得分:2)

按照你的例子,

library(data.table)
dt <- data.table(matrix(rnorm(25), 5,5))
names(dt) <- c("X/Y_1", "Y/Z_1", "X/Y_2", "Y/Z_2", "X/Y_3")
dt
         X/Y_1      Y/Z_1      X/Y_2       Y/Z_2       X/Y_3
1: -0.09845804 -0.6455857  0.2259012  1.26772833  1.14451170
2: -1.22147654  1.7643609  0.5310762 -0.46869816 -0.58761886
3: -0.61469060  1.2323381 -0.4028002  0.99903384  0.01650606
4: -0.80805337  0.2733621 -0.2855663 -0.02166544  0.59398122
5: -0.68398344  0.2891335 -0.5004021  2.12063769  0.40474155

我将首先匹配目标列

sd.cols <- grep("Y/Z", names(dt), value = T)

然后,只需使用标准data.table表示法按引用更改列。

dt[ , (sd.cols) := lapply(.SD, function(x){x^-1}), .SDcols = sd.cols ]
         X/Y_1      Y/Z_1      X/Y_2       Y/Z_2       X/Y_3
1: -0.09845804 -1.5489811  0.2259012   0.7888125  1.14451170
2: -1.22147654  0.5667775  0.5310762  -2.1335693 -0.58761886
3: -0.61469060  0.8114656 -0.4028002   1.0009671  0.01650606
4: -0.80805337  3.6581513 -0.2855663 -46.1564513  0.59398122
5: -0.68398344  3.4586094 -0.5004021   0.4715563  0.40474155