联接数据表:
X <- data.table(A = 1:4, B = c(1,1,1,1))
# A B
# 1: 1 1
# 2: 2 1
# 3: 3 1
# 4: 4 1
Y <- data.table(A = 4)
# A
# 1: 4
通过
X[Y, on = .(A == A)]
# A B
# 1: 4 1
返回预期结果。但是,我希望这行代码:
X[Y, on = .(A < A)]
# A B
# 1: 4 1
# 2: 4 1
# 3: 4 1
返回
A B
1: 1 1
2: 2 1
3: 3 1
因为关键字on
:
指示x中的哪些列应与i中的哪些列进行连接,以及要与之连接的二进制运算符的类型
根据?data.table
。没有明确提到加入的方式,当然也没有像我所猜测的那样。 <
如何精确地将x中的列与i中的列连接起来?
答案 0 :(得分:6)
在进行类似X[Y, on = .(A < A)]
data.table的非等价联接时,从A
(Y
-data.table)返回i
列。 / p>
要获得理想的结果,您可以执行以下操作:
X[Y, on = .(A < A), .(A = x.A, B)]
给出:
A B 1: 1 1 2: 2 1 3: 3 1
在下一版本中,data.table将同时返回两个A
列。 See here for the discussion。
答案 1 :(得分:6)
您部分正确。缺少的难题是(当前)当您执行任何联接时,包括使用package main
import (
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"log"
)
const Src = `
package types
import (
"io"
"net/http"
)
var (
IOReader io.Reader
Response *http.Response
)
`
const (
TypeIOReader = "IOReader"
TypeResponse = "Response"
)
func GetType(name string, pkg *types.Package) types.Type {
return pkg.Scope().Lookup(name).Type()
}
func main() {
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "types.go", Src, 0)
if err != nil {
panic(err)
}
conf := types.Config{Importer: importer.Default()}
pkg, err := conf.Check("impler/types", fset, []*ast.File{file}, nil)
if err != nil {
panic(err)
}
log.Println(types.Identical(GetType(TypeResponse, pkg), GetType(TypeResponse, pkg)))
log.Println(types.Identical(GetType(TypeIOReader, pkg), GetType(TypeIOReader, pkg)))
}
进行非等距联接时,将为联接列返回单列(在您的示例中为<
)。此列采用联接右侧的A
中的值,在这种情况下,是data.table
中A
中的值。
下面是一个示例:
我们计划在Y
的未来版本中更改此行为,以便在非等参连接的情况下都将返回两列。请参阅拉取请求https://github.com/Rdatatable/data.table/pull/2706和https://github.com/Rdatatable/data.table/pull/3093。