该data.table
包提供了许多与SQL相同的表处理方法.如果表具有键,则该键由一列或多列组成.但是一个表不能有多个键,因为它不能同时以两种不同的方式排序.
在这个例子中,X
和Y
是data.table
s的一个单一的键列"ID"; Y
还有一个非键列"x_id".
X <- data.table(id = 1:5, a=4:8,key="id")
Y <- data.table(id = c(1,1, 3,5,7), x_id=c(1,4:1), key="id")
Run Code Online (Sandbox Code Playgroud)
以下语法将在其键上连接表:
X[Y]
Run Code Online (Sandbox Code Playgroud)
如何将以下SQL语法转换为data.table代码?
select * from X join Y on X.id = Y.x_id;
Run Code Online (Sandbox Code Playgroud)
我得到的最接近的是:
Y[X,list(id, x_id),by = x_id,nomatch=0]
Run Code Online (Sandbox Code Playgroud)
但是,这不会与SQL语句执行相同的内部联接.
这是一个更清晰的例子,其中外键是y_id,我们希望连接查找Y2的值X2$y_id = Y2$id
.
X2 <- data.table(id = 1:5, y_id = c(1,1,2,2,2), key="id")
Y2 <- data.table(id = 1:5, b = letters[1:5], key="id")
Run Code Online (Sandbox Code Playgroud)
我想制作表格:
id y_id b
1 1 "a"
2 1 "a"
3 2 …
Run Code Online (Sandbox Code Playgroud) 我想了解R在将参数传递给函数,创建变量副本等时使用的逻辑与内存使用情况有关.它什么时候实际创建变量的副本而不是仅仅传递对该变量的引用?特别是我很好奇的情况是:
f <- function(x) {x+1}
a <- 1
f(a)
Run Code Online (Sandbox Code Playgroud)
是a
字面意思传递还是被传递的参考?
x <- 1
y <- x
Run Code Online (Sandbox Code Playgroud)
复制参考?什么时候不是这样的?
如果有人能向我解释这一点,我将非常感谢.
我最近发现了二进制搜索data.table
.如果表格在多个键上排序,则只能在第二个键上搜索?
DT = data.table(x=sample(letters,1e7,T),y=sample(1:25,1e7,T),rnorm(1e7))
setkey(DT,x,y)
#R> DT[J('x')]
# x y V3
# 1: x 1 0.89109
# 2: x 1 -2.01457
# ---
#384922: x 25 0.09676
#384923: x 25 0.25168
#R> DT[J('x',3)]
# x y V3
# 1: x 3 -0.88165
# 2: x 3 1.51028
# ---
#15383: x 3 -1.62218
#15384: x 3 -0.63601
Run Code Online (Sandbox Code Playgroud)
编辑:感谢@Arun
R> system.time(DT[J(unique(x), 25)])
user system elapsed
0.220 0.068 0.288
R> system.time(DT[y==25])
user system elapsed
0.268 0.092 0.359
Run Code Online (Sandbox Code Playgroud) 我有一个data.table,列有一个NA
s.我想删除该列占用特定值的行(恰好是这样""
).但是,我的第一次尝试也导致我丢失了NA
s 行:
> a = c(1,"",NA)
> x <- data.table(a);x
a
1: 1
2:
3: NA
> y <- x[a!=""];y
a
1: 1
Run Code Online (Sandbox Code Playgroud)
看了之后?`!=`
,我找到了一个有效的衬垫,但这很痛苦:
> z <- x[!sapply(a,function(x)identical(x,""))]; z
a
1: 1
2: NA
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更好的方法来做到这一点?此外,我认为没有好的方法来扩展它以排除多个非NA
值.这是一个糟糕的方式:
> drop_these <- function(these,where){
+ argh <- !sapply(where,
+ function(x)unlist(lapply(as.list(these),function(this)identical(x,this)))
+ )
+ if (is.matrix(argh)){argh <- apply(argh,2,all)}
+ return(argh)
+ }
> x[drop_these("",a)]
a
1: 1
2: NA
> x[drop_these(c(1,""),a)]
a
1: NA
Run Code Online (Sandbox Code Playgroud)
我查看?J …
论证的要点如下:
我编写的函数考虑了一个参数,一个字母数字字符串,并且应该输出一个字符串,其中该字母数字字符串的每个元素的值被切换以进行某些"映射".MRE如下:
#This is the original and switches value map
map = data.table(mapped = c(0:35), original = c(0:9,LETTERS))
#the function that I'm using:
as_numbers <- function(string) {
#split string unlisted
vector_unlisted <- unlist(strsplit(string,""))
#match the string in vector
for (i in 1:length(vector_unlisted)) {
vector_unlisted[i] <- subset(map, map$original==vector_unlisted[i])[[1]][1]
}
vector_unlisted <- paste0(vector_unlisted, collapse = "")
return(vector_unlisted)
}
Run Code Online (Sandbox Code Playgroud)
我正试图摆脱for loop
那些提高性能的东西,因为函数可以正常工作,但是对于我在这种形式下提供的元素数量而言,这是非常缓慢的:
unlist(lapply(dat$alphanum, function(x) as_numbers(x)))
Run Code Online (Sandbox Code Playgroud)
输入字符串的一个例子是:549300JV8KEETQJYUG13
.这应该会产生一个字符串5493001931820141429261934301613
在这种情况下只提供一个字符串:
> as_numbers("549300JV8KEETQJYUG13")
[1] "5493001931820141429261934301613"
Run Code Online (Sandbox Code Playgroud) 重新编码是调查数据的常见做法,但最明显的路线需要的时间比应有的多.
system.time()
在我的机器上通过提供的样本数据完成相同任务的最快代码获胜.
## Sample data
dat <- cbind(rep(1:5,50000),rep(5:1,50000),rep(c(1,2,4,5,3),50000))
dat <- cbind(dat,dat,dat,dat,dat,dat,dat,dat,dat,dat,dat,dat)
dat <- as.data.frame(dat)
re.codes <- c("This","That","And","The","Other")
Run Code Online (Sandbox Code Playgroud)
代码优化.
for(x in 1:ncol(dat)) {
dat[,x] <- factor(dat[,x], labels=re.codes)
}
Run Code Online (Sandbox Code Playgroud)
目前system.time()
:
user system elapsed
4.40 0.10 4.49
Run Code Online (Sandbox Code Playgroud)
提示:dat <- lapply(1:ncol(dat), function(x) dat[,x] <- factor(dat[,x],labels=rc)))
不是更快.
我理解如何对数据框进行排序:
df[order(df$Height),]
我理解如何过滤(或子集)匹配某个谓词的数据帧:
df[df$Weight > 120,]
但是我如何排序和过滤(例如,按高度排序并按重量过滤)?
我有一个关系数据集,我正在寻找二元信息.
我有4列.发件人,接收者,属性,边缘
我想要重复发送者 - 接收者计数并将它们转换为额外的边缘.
df <- data.frame(sender = c(1,1,1,1,3,5), receiver = c(1,2,2,2,4,5),
attribute = c(12,12,12,12,13,13), edge = c(0,1,1,1,1,0))
sender receiver attribute edge
1 1 1 12 0
2 1 2 12 1
3 1 2 12 1
4 1 2 12 1
5 3 4 13 1
Run Code Online (Sandbox Code Playgroud)
我希望最终结果如下所示:
sender receiver attribute edge
1 1 1 12 0
2 1 2 12 3
3 3 4 13 1
Run Code Online (Sandbox Code Playgroud)
重复的发送者 - 接收者之间的关系已被组合,并且重复数量包含在边数中.
任何意见都会非常感激.
谢谢!
我知道on.exit
R 中的功能,这很棒.它在调用函数退出时运行表达式,正常或作为错误的结果.
我想要的是表达式仅在调用函数正常返回时运行,而不是在出错的情况下运行.我有多个函数可以正常返回的点,以及可能失败的多个点.有没有办法做到这一点?
myfunction = function() {
...
on.exit( if (just exited normally without error) <something> )
...
if (...) then return( point 1 )
...
if (...) then return( point 2 )
...
if (...) then return( point 3 )
...
return ( point 4 )
}
Run Code Online (Sandbox Code Playgroud) 我正在使用最近推出的fread
函数data.table
来读取数据文件.当我将代码包装到knitr(Rmd)文档中时,我注意到一些奇怪的输出,即:
##
0%
Run Code Online (Sandbox Code Playgroud)
即使verbose
选项fread
设置为FALSE.我曾经sink
隐藏过这个输出,但是我想向包作者报告确切的问题.这是一个最小的例子,
library(knitr)
test = "```{r}
require(data.table)
fread('1 2 3\n')
```"
knit2html(text=test, output="test.html")
browseURL("test.html")
Run Code Online (Sandbox Code Playgroud)
什么是0%的输出?