所以我有两个数据框,信息和塔,下面有例子:
的信息:
ID Date
1132 01/09/2015
1156 02/09/2015
1132 04/09/2015
1101 04/09/2015
塔:
Tower ID1 ID2
1 1132 1101
2 1520 1156
Info的ID列中的值将始终与Towers中的ID1或ID2匹配。我想根据这些信息加入框架,所以我加入的框架应该是:
ID Date Tower
1132 01/09/2015 1
1156 02/09/2015 2
1132 04/09/2015 1
1101 04/09/2015 2
我知道dplyr的semi_join会产生类似我需要的东西,但我知道它需要在值和列名称中匹配。鉴于这些列有不同的名称,我不知道它是否会正常工作。有没有我可以在这里使用的方法?
答案 0 :(得分:3)
library(dplyr)
tidyr::gather(df2, Tower2, ID, -Tower) %>% select(-Tower2) %>% right_join(df, "ID")
<强> DF 强>
structure(list(ID = c(1132, 1156, 1132, 1101), Date = structure(c(1L,
2L, 3L, 3L), .Label = c("01/09/2015", "02/09/2015", "04/09/2015"
), class = "factor")), .Names = c("ID", "Date"), row.names = c(NA,
-4L), class = "data.frame")
<强> DF2 强>
structure(list(Tower = 1:2, ID1 = c(1132L, 1520L), ID2 = c(1101L,
1156L)), .Names = c("Tower", "ID1", "ID2"), class = "data.frame", row.names = c(NA,
-2L))
答案 1 :(得分:2)
我们可以使用melt
中的data.table
。转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df2)
),melt
来自&#39;范围&#39;长期&#39;格式和join
与原始数据集&#39; df&#39; on
&#39; ID&#39;。
library(data.table)
melt(setDT(df2), id.var="Tower", value.name = "ID")[df, on = "ID"][, variable := NULL][]
# Tower ID Date
#1: 1 1132 01/09/2015
#2: 2 1156 02/09/2015
#3: 1 1132 04/09/2015
#4: 1 1101 04/09/2015
我们也可以在没有任何连接的情况下执行此操作,并且仅使用base R
(没有外部包,没有任何循环(sapply
是伪装的循环))。在这里,我们的想法是复制第二个数据集&#39; Tower&#39;列数除了&#39; Tower&#39;之外的列数。即2
,通过names
&lt; df2&#39}的列设置该向量的unlist
。除了&#39; Tower&#39; (unlist(df2[-1])
)并使用它来匹配&#39; ID&#39;第一个数据集(as.character(df$ID)
)中的列,用于返回&#39; Tower&#39;对应于&#39; ID&#39;。
df$Tower <- setNames( rep(df2$Tower, 2), unlist(df2[-1]))[as.character(df$ID)]
df$Tower
#[1] 1 2 1 1
答案 2 :(得分:1)
使用melt
包并使用reshape2
&amp;和df
来使用df2
(@SymbolixAU在评论中建议)的另一种方法{@ 1}} @ Sumedh的帖子。
library(reshape2)
library(dplyr)
melt(df2,value.name = "ID",id.vars = "Tower") %>% right_join(df,by = "ID") %>% select(-variable)
我们也可以使用base R
reshape
函数执行此操作:
reshape(data = df2,direction = "long",varying = c("ID1","ID2"),v.names = "ID") %>% right_join(df,by = "ID") %>% select(-c(time,id))
答案 3 :(得分:1)
你真的不需要加入;只要按行分组评估,就可以创建一个新列:
Info %>% rowwise() %>%
mutate(Tower = Towers[ID == Towers$ID1 | ID == Towers$ID2, 'Tower'])
## Source: local data frame [4 x 3]
## Groups: <by row>
##
## # A tibble: 4 x 3
## ID Date Tower
## <int> <fctr> <int>
## 1 1132 01/09/2015 1
## 2 1156 02/09/2015 2
## 3 1132 04/09/2015 1
## 4 1101 04/09/2015 1
或等效于完全基础R,
Info$Tower <- sapply(Info$ID, function(x){Towers[x == Towers$ID1 | x == Towers$ID2, 'Tower']})