例如,假设我要合并df1和df2(见下文)。它们不仅具有不同的行数,还具有不同的列数。它们还有多个重复的列,以及" Sales"重复自己的专栏。我想做的是合并"销售" (不要在"销售")和"日期","价格"和" SKU" (这些列下的重复值都可以),并添加" PVC"列和填充任何缺少的单元格与NA值。基本上,这是我想要的最终产品:
Date Sales Price SKU PVC
2007/01/02 1 1.29 52648 Q
2007/01/02 2 1.99 48721 N/A
2007/01/02 5 0.55 65897 N/A
2007/01/02 6 5.00 56482 N/A
2007/01/02 10 2.50 46521 N/A
2009/01/02 4 5.99 75677 Z
这样做:
merge(df1,df2,c("Date","Sales","Price","SKU"),all=TRUE)
不起作用,因为它删除了所有4列上不完全匹配的行。尝试:
merge(df1,df2,by="Sales",all=TRUE)
不起作用,因为这会使" Sales"下的行共享相同的值。重复一遍。另外,我不想看到像" Date"," Price"和" SKU"等列。在合并的数据框中重复自己(我最后用" Date.x"," Date.y"," Price.x"," Price .y"," SKU.x"," SKU.y")。
df1
Date Sales Price SKU
2007/01/02 1 1.29 52648
2007/01/02 2 1.99 48721
2007/01/02 5 0.55 65897
2007/01/02 6 5.00 56482
2007/01/02 10 2.50 46521
DF2
Date Sales Price SKU PVC
2007/01/02 1 3.29 52647 Q
2009/01/02 4 5.99 75677 Z
答案 0 :(得分:2)
这是使用data.table
的方式:
require(data.table)
setkey(setDT(df1), Sales)
setkey(setDT(df2), Sales)
df1[df2, PVC := i.PVC]
rbind(df1, df2[!df1])
# Date Sales Price SKU PVC
# 1: 2007/01/02 1 1.29 52648 Q
# 2: 2007/01/02 2 1.99 48721 NA
# 3: 2007/01/02 5 0.55 65897 NA
# 4: 2007/01/02 6 5.00 56482 NA
# 5: 2007/01/02 10 2.50 46521 NA
# 6: 2009/01/02 4 5.99 75677 Z
setDT
将 data.frames 转换为 data.tables (无需实际复制数据)。
setkey()
在 data.tables 上按Sales
列排序数据,并将这些列标记为键列,我们将用它来加入。
在 data.tables 中,联接的格式为x[i]
,其中x
是键控data.table 和{{ 1}}可以键入也可以不键入。它通过查找与i
中每行对应的x
中的匹配行来执行连接。
因此,i
会在df1[df2]
中找到与df1
中每一行对应的所有匹配行。唯一匹配的是df2
。在该匹配项中,我们将新列Sales = 1
分配给PVC
,其值来自df1
' df2
列 - 使用PVC
表示(以区分当data.tables具有相同列名时我们引用的data.table。)
最后,我们执行非联接或反联接以获取i.PVC
中不在{{1}中的所有行(再次与键列df2
匹配)并简单地绑定以获得最终结果。
HTH
答案 1 :(得分:1)
使用library(dplyr)
:
left_join(rbind(df1,df2[,-5]) %>% group_by(Sales) %>% slice(1), df2[,c(2,5)])
这是一个解释,命令逐行分解。这样做,我使用了库magrittr
作为其%<>%
和<-
%>%
运算符
df2_noPVC <- df2 %>% select(-PVC) ## pare down df2 so they can be row-bound
bound <- rbind(df1,df2_noPVC) ## stack the dataframes
bound %<>% group_by(Sales) %>% slice(1) ## take the first row for each sale #, removing duplicates
result <- left_join(bound,df2[,c(2,5)]) ## now that you have the unique records, merge back the PVC field
扭曲来自于merge
和rbind
的组合。如果您希望来自df2
而不是df1
的Sales = 1记录,那么这将是一个更简单的问题,您可以rbind
和slice
(重复数据删除)合并。
答案 2 :(得分:0)
base::merge
和dplyr
的混合。绝对不是最漂亮的解决方案。我有兴趣看到有人提供更好的解决方案,因为我确定只有merge
或简单的dplyr
字符串。
df<- rbind(merge(df1,df2[,c(2,5)],by=c("Sales"),all.x=TRUE),df2) %>%
group_by(Sales) %>%
filter(row_number(desc(Sales)) == 1) %>%
arrange(Sales)
Sales Date Price SKU PVC
1 1 2007/01/02 1.29 52648 Q
2 2 2007/01/02 1.99 48721 NA
3 4 2009/01/02 5.99 75677 Z
4 5 2007/01/02 0.55 65897 NA
5 6 2007/01/02 5.00 56482 NA
6 10 2007/01/02 2.50 46521 NA