我在Ubuntu工作站上运行R,它有8个虚拟内核和8 Gb内存.我希望经常使用多核软件包来并行使用8个核心; 但是我发现整个R过程重复了8次.由于R实际上似乎使用了比gc中报告的更多的内存(即使在gc()之后也是如此),这意味着即使相对温和的内存使用(一个200Mb对象)在重复8次时变得难以处理内存.我调查了bigmemory让子进程共享相同的内存空间; 但它需要对我的代码进行一些重大改写,因为它不处理数据帧.
有没有办法在分叉之前使R尽可能精简,即让OS尽可能多地回收内存?
编辑:我想我明白现在发生了什么.问题不在我想象的地方 - 父线程中存在且未被操纵的对象不会重复八次.相反,我的问题来自于我正在使每个子进程执行的操作的性质.每个人都必须操纵一个具有数十万级别的重要因素,我认为这是一个记忆很重的一点.结果,确实存在总存储器负载与核心数成比例的情况; 但没有我想象的那么戏剧化.我学到的另一个教训是,有4个物理内核+超线程的可能性,超线程实际上对于R来说通常不是一个好主意.增益很小,内存成本可能非常重要.所以我从现在开始研究4核.
对于那些想要试验的人来说,这是我运行的代码类型:
# Create data
sampdata <- data.frame(id = 1:1000000)
for (letter in letters) {
sampdata[, letter] <- rnorm(1000000)
}
sampdata$groupid = ceiling(sampdata$id/2)
# Enable multicore
library(multicore)
options(cores=4) # number of cores to distribute the job to
# Actual job
system.time(do.call("cbind",
mclapply(subset(sampdata, select = c(a:z)), function(x) tapply(x, sampdata$groupid, sum))
))
Run Code Online (Sandbox Code Playgroud) 我在使用mutate{dplyr}函数时遇到问题,目的是向数据框添加新列.我想要一个新的列是字符类型,并包含来自其他列(也是字符类型)的排序单词的"concat".例如,对于以下数据框:
> library(datasets)
> states.df <- data.frame(name = as.character(state.name),
+ region = as.character(state.region),
+ division = as.character(state.division))
>
> head(states.df, 3)
name region division
1 Alabama South East South Central
2 Alaska West Pacific
3 Arizona West Mountain
Run Code Online (Sandbox Code Playgroud)
我想获得一个包含以下第一个元素的新列:
"Alamaba_East South Central_South"
Run Code Online (Sandbox Code Playgroud)
我试过这个:
mutate(states.df,
concated_column = paste0(sort(name, region, division), collapse="_"))
Run Code Online (Sandbox Code Playgroud)
但我收到一个错误:
Error in sort(1:50, c(2L, 4L, 4L, 2L, 4L, 4L, 1L, 2L, 2L, 2L, 4L, 4L, :
'decreasing' must be a length-1 logical vector.
Did you intend to …Run Code Online (Sandbox Code Playgroud) 我需要将我的宽表重新整形为长格式,但为每条记录保留多个字段,例如:
dw <- read.table(header=T, text='
sbj f1.avg f1.sd f2.avg f2.sd blabla
A 10 6 50 10 bA
B 12 5 70 11 bB
C 20 7 20 8 bC
D 22 8 22 9 bD
')
# Now I want to melt this table, keeping both AVG and SD as separate fields for each measurement, to get something like this:
# sbj var avg sd blabla
# A f1 10 6 bA
# A f2 50 10 bA
# B …Run Code Online (Sandbox Code Playgroud) 我试图在R中的data.table中存在重复键时理解J()查找的逻辑.
这是我尝试过的一个小实验:
library(data.table)
options(stringsAsFactors = FALSE)
x <- data.table(keyVar = c("a", "b", "c", "c"),
value = c( 1, 2, 3, 4))
setkey(x, keyVar)
y1 <- data.frame(name = c("d", "c", "a"))
x[J(y1$name), ]
## OK
y2 <- data.frame(name = c("d", "c", "a", "b"))
x[J(y2$name), ]
## Error: see below
x2 <- data.table(keyVar = c("a", "b", "c"),
value = c( 1, 2, 3))
setkey(x2, keyVar)
x2[J(y2$name), ]
## OK
Run Code Online (Sandbox Code Playgroud)
我得到的错误消息是:
Error in vecseq(f__, len__, if (allow.cartesian) NULL else as.integer(max(nrow(x), :
Join results …Run Code Online (Sandbox Code Playgroud) 这个问题适用于创建"宽"表,类似于您可以使用reshape2中的dcast创建的表.我知道之前已经讨论了很多次,但我的问题是如何使这个过程更有效率.我在下面提供了几个例子,这些例子可能会使问题看起来很冗长,但大多数只是用于基准测试的测试代码
从一个简单的例子开始,
> z <- data.table(col1=c(1,1,2,3,4), col2=c(10,10,20,20,30),
col3=c(5,2,2.3,2.4,100), col4=c("a","a","b","c","a"))
> z
col1 col2 col3 col4
1: 1 10 5.0 a # col1 = 1, col2 = 10
2: 1 10 2.0 a # col1 = 1, col2 = 10
3: 2 20 2.3 b
4: 3 20 2.4 c
5: 4 30 100.0 a
Run Code Online (Sandbox Code Playgroud)
我们需要创建一个"宽"表,它将col4列的值作为列名,并将col1和col2的每个组合的和(col3)值组合在一起.
> ulist = unique(z$col4) # These will be the additional column names
# Create long table with sum
> z2 <- z[,list(sumcol=sum(col3)), by='col1,col2,col4']
# Pivot …Run Code Online (Sandbox Code Playgroud) 这个问题是由Abiel Reinhart在这里提交的一个错误所驱动的data.table.我注意到同样的事情也发生了data.frame.
这是一个例子:
DF <- data.frame(x=1:5, y=6:10)
> DF*DF
x y
1 1 36
2 4 49
3 9 64
4 16 81
5 25 100
> class(DF*DF) # [1] "data.frame"
> DF^2
x y
[1,] 1 36
[2,] 4 49
[3,] 9 64
[4,] 16 81
[5,] 25 100
> class(DF^2) # [1] "matrix"
Run Code Online (Sandbox Code Playgroud)
为什么"^"将其强制转换为矩阵?有任何想法吗?请注意,由解析器**转换为^.所以,做DF**2会得到与之相同的结果DF^2.
我没有找到与此强制有关的任何内容?`^`.
编辑:尼尔的回答清楚地显示^ …
我绘制了一个景点的访问时间分布,从一天0到23小时.我想调整x轴的间隔,让所有小时都显示出来.我怎样才能做到这一点?
d = c(42,13,10,3,2,6,7,15,38,63,128,153,178,181,236,217,272,417,526,653,607,385,191,70)
plot(seq(0,23,by=1),c,type='b',col='red',main="Confucius Temple",xlab="Hours",ylab="Numbers of check-in")
Run Code Online (Sandbox Code Playgroud)

这是我认为应该问这个问题的问题.我想在R-forge跟踪器中将其作为一个错误/不一致之前确认是否存在错误/不一致.
考虑一下data.table:
require(data.table)
DT <- data.table(x=c(1,0,NA), y=1:3)
Run Code Online (Sandbox Code Playgroud)
现在,要访问不是 0 的DT的所有行,我们可以通过以下方式执行:
DT[x != 0]
# x y
# 1: 1 1
DT[!(x == 0)]
# x y
# 1: 1 1
# 2: NA 3
Run Code Online (Sandbox Code Playgroud)
当基础逻辑操作等效时,访问DT[x != 0]并DT[!(x==0)]给出不同的结果.
注:转换到这一个data.frame和运行这些操作会给结果彼此两个逻辑上是等价的操作相同,但结果是不同的两种data.table结果.有关原因的解释,请?`[`参阅本节NAs in indexing.
编辑:由于你们中的一些人已经强调要求平等data.frame,这里是data.frame上相同操作的输出片段:
DF <- as.data.frame(DT)
# check ?`[` under the section `NAs in indexing` as to why this happens
DF[DF$x != 0, …Run Code Online (Sandbox Code Playgroud) 如何使用data.table执行以下(直接使用sqldf)并得到完全相同的结果:
library(data.table)
whatWasMeasured <- data.table(start=as.POSIXct(seq(1, 1000, 100),
origin="1970-01-01 00:00:00"),
end=as.POSIXct(seq(10, 1000, 100), origin="1970-01-01 00:00:00"),
x=1:10,
y=letters[1:10])
measurments <- data.table(time=as.POSIXct(seq(1, 2000, 1),
origin="1970-01-01 00:00:00"),
temp=runif(2000, 10, 100))
## Alternative short names for data.tables
dt1 <- whatWasMeasured
dt2 <- measurments
## Straightforward with sqldf
library(sqldf)
sqldf("select * from measurments m, whatWasMeasured wwm
where m.time between wwm.start and wwm.end")
Run Code Online (Sandbox Code Playgroud) 我有以下数据框surge:
MeshID StormID Rate Surge Wind
1 1412 1.0000E-01 0.01 0.0
2 1412 1.0000E-01 0.03 0.0
3 1412 1.0000E-01 0.09 0.0
4 1412 1.0000E-01 0.12 0.0
5 1412 1.0000E-01 0.02 0.0
6 1412 1.0000E-01 0.02 0.0
7 1412 1.0000E-01 0.07 0.0
1 1413 1.0000E-01 0.06 0.0
2 1413 1.0000E-01 0.02 0.0
3 1413 1.0000E-01 0.05 0.0
Run Code Online (Sandbox Code Playgroud)
我使用以下代码来查找每次风暴的最大浪涌值:
MaxSurge <- data.frame(tapply(surge[,4], surge[,2], max))
Run Code Online (Sandbox Code Playgroud)
它返回:
1412 0.12
1413 0.06
Run Code Online (Sandbox Code Playgroud)
这很好,除了我还希望它包含MeshID在浪涌最大的点处的值.我知道我可能会使用which.max,但我无法弄清楚如何将其付诸行动.我对R编程非常陌生.