R 中 data.table 中的逻辑索引
logical indexing in data.table in R
我是 data.table 的初学者,我正在尝试做一个非常简单的操作,在基础数据帧中看起来像这样:
percentages[percentages<0] = abs(percentages[percentages<0])
数据如下所示:
percentages
p1 p2 p3
1: 0.689 0.206 0.106
到目前为止,我找到的 data.table 的解决方案只是获取数据:
percentages[,which(percentages<0),with=FALSE]
但它比 dataframe 更复杂...应该有更好的东西,但我什么也得不到...有什么建议吗?
一般选项可能正在使用 set
。它包括一个 for
循环,但它会更有效,因为我们在列中循环而不是通过执行创建 matrix
(df1 < 0
- 对于巨大的数据集,这会消耗一些内存) .使用 set
会很有效,因为文档中说 [.data.table
的开销可以避免
for(j in seq_along(df1)){
set(df1, i = which(df1[[j]]<0), j=j, value = abs(df1[[j]]))
}
由于 OP 需要单行代码,对于显示的单行示例,
df1[, lapply(.SD, function(x) replace(x, x < 0, abs(x)))]
基准
基于 system.time
稍微大一点的数据集
set.seed(42)
dfN <- data.frame(p1 = rnorm(1e7), p2 = rnorm(1e7), p3 = rnorm(1e7), p4 = rnorm(1e7))
dfN1 <- copy(dfN)
setDT(dfN1)
system.time({
i1 <- dfN < 0
dfN[i1] <- abs(dfN[i1])
})
# user system elapsed
# 1.63 0.50 2.12
system.time({
for(j in seq_along(dfN1)){
set(dfN1, i = which(dfN1[[j]]<0), j=j, value = abs(dfN1[[j]][dfN1[[j]]<0]))
}
})
# user system elapsed
# 0.91 0.08 0.98
正如阿克伦在上面发布的那样,单行回复是
df1[, lapply(.SD, function(x) replace(x, x < 0, abs(x)))]
然而,这并不是我想要的,因为 data.table 在语法上似乎比 data.frame 复杂得多(至少在这个例子中是这样)
我们基本上是在 data.table 中自己进行矢量化(使用 lapply),而在 data.frame 中它自动发生
我是 data.table 的初学者,我正在尝试做一个非常简单的操作,在基础数据帧中看起来像这样:
percentages[percentages<0] = abs(percentages[percentages<0])
数据如下所示:
percentages
p1 p2 p3
1: 0.689 0.206 0.106
到目前为止,我找到的 data.table 的解决方案只是获取数据:
percentages[,which(percentages<0),with=FALSE]
但它比 dataframe 更复杂...应该有更好的东西,但我什么也得不到...有什么建议吗?
一般选项可能正在使用 set
。它包括一个 for
循环,但它会更有效,因为我们在列中循环而不是通过执行创建 matrix
(df1 < 0
- 对于巨大的数据集,这会消耗一些内存) .使用 set
会很有效,因为文档中说 [.data.table
的开销可以避免
for(j in seq_along(df1)){
set(df1, i = which(df1[[j]]<0), j=j, value = abs(df1[[j]]))
}
由于 OP 需要单行代码,对于显示的单行示例,
df1[, lapply(.SD, function(x) replace(x, x < 0, abs(x)))]
基准
基于 system.time
稍微大一点的数据集
set.seed(42)
dfN <- data.frame(p1 = rnorm(1e7), p2 = rnorm(1e7), p3 = rnorm(1e7), p4 = rnorm(1e7))
dfN1 <- copy(dfN)
setDT(dfN1)
system.time({
i1 <- dfN < 0
dfN[i1] <- abs(dfN[i1])
})
# user system elapsed
# 1.63 0.50 2.12
system.time({
for(j in seq_along(dfN1)){
set(dfN1, i = which(dfN1[[j]]<0), j=j, value = abs(dfN1[[j]][dfN1[[j]]<0]))
}
})
# user system elapsed
# 0.91 0.08 0.98
正如阿克伦在上面发布的那样,单行回复是
df1[, lapply(.SD, function(x) replace(x, x < 0, abs(x)))]
然而,这并不是我想要的,因为 data.table 在语法上似乎比 data.frame 复杂得多(至少在这个例子中是这样)
我们基本上是在 data.table 中自己进行矢量化(使用 lapply),而在 data.frame 中它自动发生