R中的自连接
下面是一个tibble示例:R中的自连接,r,dataframe,join,dplyr,tibble,R,Dataframe,Join,Dplyr,Tibble,下面是一个tibble示例: test <- tibble(a = c("dd1","dd2","dd3","dd4","dd5"), name = c("a", "b", "c", "d", "e"), b = c("dd3","dd4","dd1","dd5","dd2")) 我的表太大了(2.7M行4列),出现以下错误: 错误:std::错误\u alloc 请告知如何正确操作/最佳实践 我的最终目标是获得以下结构:
test <- tibble(a = c("dd1","dd2","dd3","dd4","dd5"),
name = c("a", "b", "c", "d", "e"),
b = c("dd3","dd4","dd1","dd5","dd2"))
我的表太大了(2.7M行4列),出现以下错误:
错误:std::错误\u alloc
请告知如何正确操作/最佳实践
我的最终目标是获得以下结构:
a name b b_name
dd1 a dd3 c
dd2 b dd4 d
dd3 c dd1 a
dd4 d dd5 e
dd5 e dd2 b
对于这样的行数,我认为
data.table
可能会给您带来更快的速度。下面是data.table解决方案:
library(data.table)
setDT(test)
方法1:自连接:
方法2:使用数据。表::合并:
下面是另一个使用
base
中的match
函数和dplyr
包中的mutate
的简单解决方案:
library(dplyr)
new_test <- test %>%
mutate(b_name = name[match(test$b,test$a)])
库(dplyr)
新测试%
变异(b_name=name[匹配(测试$b,测试$a)])
但是,要小心使用很长的表,因为
match
可能不是最佳的实现。另一个选项是fmatch
fromfastmatch
library(fastmatch)
test$b_name <- with(test, name[fmatch(b, a)])
test$b_name
#[1] "c" "d" "a" "e" "b"
库(快速匹配)
测试$b_name我没有收到此错误。但是我收到了一个关于a
列的额外列。@yarnabrina对不起,我刚刚编辑了这个问题,这个问题对你的长表有效吗?:new\u test%mutate(b\u name=name[match(test$b,test$a)])
@VitaliAvagyan工作得很好,检查是否符合要求。请添加作为答案并解释。不起作用…>vecseq(f_uuu,len_uuu,if(allow.cartesian | | notjoin | | | |!anyDuplicated(f_uuu,):连接结果超过2^31行(内部vecseq达到物理限制)。很可能是指定错误的联接。请检查i中是否存在重复的键值,其中每个键值都会一次又一次地联接到x中的同一组。如果没有问题,请尝试by=.EACHI为每个组运行j以避免较大的分配。否则,请在常见问题解答、Wiki、堆栈溢出和data.table问题跟踪器中搜索此错误消息以获取建议。“检查i中是否存在重复的键值,每个键值都会反复加入x中的同一组。"这并不是说它不起作用,而是因为你有很多重复的值,这导致了一个巨大的data.frame。如果你真的需要那堆重复的值,你可以尝试by=.EACHI
,但当然,由于物理大小的限制,这可能不起作用。删除重复的值可能/合理吗?Vitaly showed是一个非常简单的匹配解决方案,它是有效的。它应该是一个简单的连接,但由于某些原因它不起作用。你怎么看?a和b之间的交集是3499,共有3500个可能的唯一id。请再次查看df,我有一个id和b id,它们来自同一组可能的id。其中一个被命名,我需要为其他id添加名称这是一个等级关系。你能告诉我怎么解决吗?@pavodive
merge(test, test, by.x = "a", by.y = "b")
library(dplyr)
new_test <- test %>%
mutate(b_name = name[match(test$b,test$a)])
library(fastmatch)
test$b_name <- with(test, name[fmatch(b, a)])
test$b_name
#[1] "c" "d" "a" "e" "b"