- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果我使用列名称获取表的切片,R 是否会分配内存以将切片保存在新位置?具体来说,我有一个包含深度 1 和深度 2 等列的表。我想添加包含两者的最大值和最小值的列。我有两种方法:
dd = dat[,c("depth1","depth2")]
dat$mindepth = apply(dd,1,min)
dat$maxdepth = apply(dd,1,max)
remove(dd)
或
dat$mindepth = apply(dat[,c("depth1","depth2")],1,min)
dat$maxdepth = apply(dat[,c("depth1","depth2")],1,max)
如果我没有用完新内存,我宁愿只使用一次切片,否则我想保存重新分配。哪一个更好?在处理大型数据集时,内存问题可能很关键,因此请不要用万恶模因的根源来否决这一问题。
最佳答案
我知道这实际上并不能回答问题的主旨(@hadley 已经做到了这一点并且值得赞扬),但是对于您建议的选项还有其他选择。在这里,您可以使用 pmin()
和 pmax()
作为另一种解决方案,并使用 with()
或 within()
我们无需显式子集即可创建 dd
。
R> set.seed(1)
R> dat <- data.frame(depth1 = runif(10), depth2 = runif(10))
R> dat <- within(dat, mindepth <- pmin(depth1, depth2))
R> dat <- within(dat, maxdepth <- pmax(depth1, depth2))
R>
R> dat
depth1 depth2 mindepth maxdepth
1 0.26550866 0.2059746 0.20597457 0.2655087
2 0.37212390 0.1765568 0.17655675 0.3721239
3 0.57285336 0.6870228 0.57285336 0.6870228
4 0.90820779 0.3841037 0.38410372 0.9082078
5 0.20168193 0.7698414 0.20168193 0.7698414
6 0.89838968 0.4976992 0.49769924 0.8983897
7 0.94467527 0.7176185 0.71761851 0.9446753
8 0.66079779 0.9919061 0.66079779 0.9919061
9 0.62911404 0.3800352 0.38003518 0.6291140
10 0.06178627 0.7774452 0.06178627 0.7774452
我们可以查看 tracemem()
进行了多少复制,但仅如果您的 R 是在激活以下配置选项的情况下编译的--enable-内存分析
。
R> set.seed(1)
R> dat <- data.frame(depth1 = runif(10), depth2 = runif(10))
R> tracemem(dat)
[1] "<0x2641cd8>"
R> dat <- within(dat, mindepth <- pmin(depth1, depth2))
tracemem[0x2641cd8 -> 0x2641a00]: within.data.frame within
tracemem[0x2641a00 -> 0x2641878]: [<-.data.frame [<- within.data.frame within
R> tracemem(dat)
[1] "<0x2657bc8>"
R> dat <- within(dat, maxdepth <- pmax(depth1, depth2))
tracemem[0x2657bc8 -> 0x2c765d8]: within.data.frame within
tracemem[0x2c765d8 -> 0x2c764b8]: [<-.data.frame [<- within.data.frame within
因此我们看到 R 在每次 within()
调用期间复制了 dat
两次。将其与您的两个建议进行比较:
R> set.seed(1)
R> dat <- data.frame(depth1 = runif(10), depth2 = runif(10))
R> tracemem(dat)
[1] "<0x2e1ddd0>"
R> dd <- dat[,c("depth1","depth2")]
R> tracemem(dd)
[1] "<0x2df01a0>"
R> dat$mindepth = apply(dd,1,min)
tracemem[0x2df01a0 -> 0x2cf97d8]: as.matrix.data.frame as.matrix apply
tracemem[0x2e1ddd0 -> 0x2cc0ab0]:
tracemem[0x2cc0ab0 -> 0x2cc0b20]: $<-.data.frame $<-
tracemem[0x2cc0b20 -> 0x2cc0bc8]: $<-.data.frame $<-
R> tracemem(dat)
[1] "<0x26b93c8>"
R> dat$maxdepth = apply(dd,1,max)
tracemem[0x2df01a0 -> 0x2cc0e30]: as.matrix.data.frame as.matrix apply
tracemem[0x26b93c8 -> 0x26742c8]:
tracemem[0x26742c8 -> 0x2674358]: $<-.data.frame $<-
tracemem[0x2674358 -> 0x2674478]: $<-.data.frame $<-
这里,dd
在每次调用 apply
时都会被复制一次,因为 apply()
将 dd
转换为继续之前的矩阵。每个 tracemem
输出 block 中的最后三行表示正在制作三个 dat
副本来插入新列。
你的第二个选择怎么样?
R> set.seed(1)
R> dat <- data.frame(depth1 = runif(10), depth2 = runif(10))
R> tracemem(dat)
[1] "<0x268bc88>"
R> dat$mindepth <- apply(dat[,c("depth1","depth2")],1,min)
tracemem[0x268bc88 -> 0x26376b0]:
tracemem[0x26376b0 -> 0x2637720]: $<-.data.frame $<-
tracemem[0x2637720 -> 0x2637790]: $<-.data.frame $<-
R> tracemem(dat)
[1] "<0x2466d40>"
R> dat$maxdepth <- apply(dat[,c("depth1","depth2")],1,max)
tracemem[0x2466d40 -> 0x22ae0d8]:
tracemem[0x22ae0d8 -> 0x22ae1f8]: $<-.data.frame $<-
tracemem[0x22ae1f8 -> 0x22ae318]: $<-.data.frame $<-
这里,此版本避免了设置 dd
中涉及的副本,但在所有其他方面与您之前的建议类似。
我们还能做得更好吗?是的,一种简单的方法是使用我开始使用的 within()
选项,但执行这两个语句以在对 within()
的一次调用:
R> set.seed(1)
R> dat <- data.frame(depth1 = runif(10), depth2 = runif(10))
R> tracemem(dat)
[1] "<0x21c4158>"
R> dat <- within(dat, { mindepth <- pmin(depth1, depth2)
+ maxdepth <- pmax(depth1, depth2) })
tracemem[0x21c4158 -> 0x21c44a0]: within.data.frame within
tracemem[0x21c44a0 -> 0x21c4628]: [<-.data.frame [<- within.data.frame within
在此版本中,与原始 within()
版本的 4 个副本相比,我们仅调用 dat
的两个副本。
如果我们将 dat
强制转换为矩阵然后进行插入会怎样?
R> set.seed(1)
R> dat <- data.frame(depth1 = runif(10), depth2 = runif(10))
R> tracemem(dat)
[1] "<0x1f29c70>"
R> mat <- as.matrix.data.frame(dat)
tracemem[0x1f29c70 -> 0x1f09768]: as.matrix.data.frame
R> tracemem(mat)
[1] "<0x245ff30>"
R> mat <- cbind(mat, pmin(mat[,1], mat[,2]), pmax(mat[,1], mat[,2]))
R>
这是一个改进,因为在强制转换为矩阵时,我们仅产生 dat
的单个副本的成本。我通过直接调用 as.matrix.data.frame()
方法进行了一些作弊。如果我们只使用 as.matrix()
,我们就会产生另一个 mat
副本。
这凸显了矩阵使用起来比数据框快得多的原因之一。
关于r - R中表切片占用内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5332708/
我有一张用户表 users +------+ - user_id ... ... - updated_by 据我所知,updated_by 列应该在 user_id 列上引用此表。我不确定,这
我是 SQL 新手,我有 2 个包含这些列的表: table structures__|id|name|nation_id|image| table nations______|id|nation|
我正在使用 codeigniters sql 选择来选择不在一组 id 中的用户。 $this->db->select('fbuid')->where_in('fbuid', $friends); $
找不到具体的答案所以我想问一下。简而言之,我有一个表,它根据存储在我的数据库中的数据从 API 检索信息,我想要做的就是从该表中获取某些列的总数,而不是全部列,以便我可以在其他地方使用它们网站。例如,
这是 phpMyAdmin 为我生成的 SQL 语句: SELECT * FROM `table_name` WHERE 1 可以看到 table_name 被 ` 字符包围。 为什么? 最佳答案 用
我有两个这样的表 我想在这里从 Table1 插入到 Table2。这就是我想要的。 取 MOU = 10。它在同一行中有 num1 和 hour1。我想将它插入到与 num1 同一行与 hour1
我的任务是使用 C++ 编写一个程序,以使用 Gamma 分布计算概率。如果我已经找到函数值,如何将其更改为 Gamma 分布表中的值?我不知道公式。 例如Fg(8;8),在表中为0.5470。而表中
我在查看 HTML 电子邮件时遇到问题,需要格式化 css 以与 HTML 脚本内联。 我有多个表使用的以下 td css。 td.gridtopleft { border-left: solid
我正在使用来自 pip 的最新 sqlalchemy 和最新的 pymssql 连接 mssql 服务器 8.00.2039(2005 年?)困难在于表和列名称是俄语。是否可以用 sqlalchemy
我有一个有趣的问题 - 我需要 JOIN 语句的完全相反。 我有一个名为 invoices 的表和另一个名为 payments 的表。我想按顺序检索没有任何付款的发票,但之后是有付款的行。 发票表有这
我有两个表: 主题:[id, ...] 类别:[主题.id, ...] 我想从表 #1 中选择所有主题,但不包含 #2(类别)中的条目。 任何提示表示赞赏(: 最好的问候 最佳答案 Sachin 已经
MYSQL: 我正在使用表 information_schema.tables 中的 AUTO_INCRMENT 列来获取下一个 id。 如下: SELECT AUTO_INCREMENT FROM
我是一名优秀的程序员,十分优秀!