我到处寻找,我似乎无法找到解决这个小问题的可行办法。
我有两个大数据集,N = 875和N = 922。
df.1
数据设置为875 obs和27 var
df.2
数据设置为922 obs 23 var
df.1
包含FIRST
和LAST
列,这些列是个人的名字和姓氏,以及其他25个列。
df.2
列X1
和X2
对应于个人的名字和姓氏,以及其他21个列。
我需要将df.1
与df.2
合并,并丢弃任何不在两个帧中的观察结果。
所以我现在应该有一个少于875个观测值和48列的数据框。
有什么建议吗?
由于
答案 0 :(得分:4)
考虑到df1和df2的变量名称完全相同,您可以尝试
merge(df1, df2, by = c('X1', 'X2'), all = F)
在您的情况下,您需要
merge(df.1, df.2, by.x = c('FIRST', 'LAST'), by.y = c('X1', 'X2'))
对于提供的数据集:
library(XML)
url1 <- "http://stats.nhlnumbers.com/player_stats/year/2010"
df1 <- readHTMLTable(url1)
names <- data.frame(do.call(rbind, strsplit(as.character(df1[[1]][ ,1]),
split = ", ")))
df1 <- cbind(df1, names)
#head(df1)
url2 <- "http://stats.nhlnumbers.com/player_stats/year/2009"
df2 <- readHTMLTable(url2)
names2 <- data.frame(do.call(rbind, strsplit(as.character(df2[[1]][ ,1]),
split = ", ")))
df2 <- cbind(df2, names2)
#head(df2)
df1_2 <- merge(df1, df2, by = c('X1', 'X2'), all = F)
head(subset(df1_2, select = c('X1', 'X2', 'skaters-data.Name.x',
'NULL.PTS/$MM.x', 'NULL.PTS/$MM.y')))
df1_2$Player <- paste(df1_2$X2, df1_2$X1)
url3 <- "http://hockey-reference.com/leagues/NHL_2010_skaters.html"
df3 <- readHTMLTable(url3)
df3 <- as.data.frame(df3)
df4 <- merge(df1_2, df3, by.x = 'Player', by.y = 'stats.Player', all = F)
names(df4) <- gsub("[[:punct:]]", "_", names(df4))
head(subset(df4, select = c(X2, X1, Player, NULL_PTS__MM_x,
NULL_PTS__MM_y, stats_Rk)))
X2 X1 Player NULL_PTS__MM_x NULL_PTS__MM_y stats_Rk
1 Aaron Johnson Aaron Johnson 18.519 15.573 344
2 Aaron Rome Aaron Rome 7.619 6.698 662
3 Aaron Voros Aaron Voros 7.000 16.000 825
4 Aaron Ward Aaron Ward 5.200 4.000 834
5 Adam Burish Adam Burish 5.614 12.632 95
6 Adam Foote Adam Foote 3.000 2.333 228
也许可以画出来
df5 <- subset(df4, select = c(X2, X1, Player, NULL_PTS__MM_x,
NULL_PTS__MM_y, stats_Rk))[1:10, ]
library(ggplot2)
ggplot(aes(x = as.numeric(NULL_PTS__MM_x), y = as.numeric(stats_Rk),
colour = Player), data = df5) +
geom_point()
答案 1 :(得分:3)
除base::merge
外,还有一种方法是使用SQL
。
您可以将R
与sqldf
一起使用(但将您的数据重命名为df1
和df2
而不使用点.
)
library(sqldf )
sqldf("SELECT *
FROM df1, df2
WHERE df1.FIRST==df2.X1
and df1.LAST == df2.X2")
另一种选择是data.table
,如果你有大数据集,你应该考虑这个:
library(data.table)
dt1 <- data.table(df1, key=c("FIRST", "LAST")) #set keys
dt2 <- data.table(df2, key=c("X1", "X2")) #set keys
dt1[dt2] #join
从data.table
版本&gt; = 1.9开始,有一个函数setDT
可将data.frame
(以及list
)转换为{{1} } 引用。这样可以提高速度和内存效率(特别是在数据为5GB且内存为8GB的情况下)。所以,可以这样做:
data.table