【发布时间】:2017-03-10 14:24:44
【问题描述】:
我有一个大的data.table,有数百列和数千行。大多数列都包含像 X/Y 或 Y/Z 等比率的数值。
我需要翻转一些这些比率,以便它们从 Y/Z -> Z/Y 转换。我对这些列的唯一指示是包含子字符串“x/y”或“y/z”的列名。
我可以使用grepl 获取与“y/z”匹配的列,但我不确定如何使用apply/lapply 等的逻辑值数组。我意识到我可以提取列(通过逻辑索引或.SDcols)并转换它们,但我不想丢弃/忽略剩余的列。
最后,我尝试过这样的事情
flipcols <- grepl("Y/Z", names(sites))
sites.new <- sites[, , lapply(.SD, function(x) 1/x), .SDcols = flipcols]
但是sites和sites.new没有区别,应该转换的列没有转换,对应列之间的总和差为0。
建议?
编辑:在@akrun 之后,我尝试了 := 运算符,但它会导致以下其他问题:
# 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'
EDIT2:这是一个最小示例,目标是转换与“Y/Z”模式匹配的列(此处最小示例中的第二个和第四个),而 保持其他列不变并保留部分结果。
> 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: 1.5972490 -0.01763484 1.10745607 -0.1416583 -0.4632829
2: 0.6629621 -0.82719204 -1.68214956 0.6145526 -0.8169235
3: -0.7491393 -0.05290791 0.63935066 1.0665537 -1.9107424
4: -0.6804972 -0.40107880 -0.01030063 1.4566075 -0.6866042
5: 0.2505391 -0.29091850 -1.95926987 0.8733446 1.3909565
【问题讨论】:
-
在
lapply之前有两个,,,应该是sites[, lapply(.SD, ..。 data.table 的一般格式,即dt[i, j, by] -
@akrun 是正确的,但是通过删除逗号,我有效地只选择了我操作的列。我还需要返回未触及的列
-
在这种情况下,使用赋值
:=即sites[, (flipcols) := lapply(.SD, function(x) 1/x), .SDcols = flipcols] -
@akrun 你是什么意思?我应该如何使用运算符?
-
你在这里弄错了逗号。在问太多问题之前,请在你的帖子中放一个具体的例子,这样 akrun 可以根据上下文来说明他的答案。
标签: r data.table lapply