2015-05-29 29 views
3

我從Excel切換到R和想知道如何在R.
做到這一點我有一個數據集,看起來是這樣的:插值/查找R中

df1<-data.frame(Zipcode=c("7941AH","7941AG","7941AH","7941AZ"), 
       From=c(2,30,45,1), 
       To=c(20,38,57,8), 
       Type=c("even","mixed","odd","mixed"), 
       GPS=c(12345,54321,11221,22331)) 

df2<-data.frame(zipcode=c("7914AH", "7914AH", "7914AH", "7914AG","7914AG","7914AZ"), 
       housenum=c(18, 19, 50, 32, 104,11)) 

第一數據集包含郵政編碼,門牌號碼範圍(從和到),如果範圍包含偶數,奇數或混合門牌號碼和GPS座標,請輸入含義。第二個數據集只包含地址(郵編,門牌號碼)。

我想要做的是查找df2的gps座標。對於郵編7941AG和housenumber 18(甚至2至20號),例如地址GPS座標12345

更新: 因爲它沒有過我的腦海,該數據集的大小是選擇的重要解決方案(我知道,有點幼稚......)這裏有一些額外的信息: df1的實際大小是472.000觀測值,df2有110萬觀測值。 df1中唯一的郵編數量爲280.000。我偶然發現了這個帖子speed up the loop operation in R 了一些有趣的結果,但我不知道如何通過@josilber提供的解決方案將這一

+1

你是否在你的例子中使用'7941AH'?你的'df1'不包括從2到20的7941AG。 – r2evans

回答

1

給定較大的數據框,您最好的選擇可能是合併df1df2他們的郵政編碼(也就是從他們具有相同郵政編碼的數據框中獲取每一對行),按照門牌號過濾,刪除重複項(來自df1的多個規則匹配的情況),然後存儲關於所有匹配房屋的信息。讓我們開始與您指定的大小的樣本數據集:

set.seed(144) 
df1 <- data.frame(Zipcode=sample(1:280000, 472000, replace=TRUE), 
        From=sample(1:50, 472000, replace=TRUE), 
        To=sample(51:100, 472000, replace=TRUE), 
        Type=sample(c("even", "odd", "mixed"), 472000, replace=TRUE), 
        GPS=sample(1:100, 472000, replace=TRUE)) 
df2 <- data.frame(zipcode=sample(1:280000, 1.1e6, replace=TRUE), 
        housenum=sample(1:100, 1.1e6, replace=TRUE)) 

現在我們可以進行GPS數據的高效計算:

get.gps <- function(df1, df2) { 
    # Add ID to df2 
    df2$id <- 1:nrow(df2) 
    m <- merge(df1, df2, by.x="Zipcode", by.y="zipcode") 
    m <- m[m$housenum >= m$From & 
     m$housenum <= m$To & 
     (m$Type == "mixed" | 
      (m$Type == "odd" & m$housenum %% 2 == 1) | 
      (m$Type == "even" & m$housenum %% 2 == 0)),] 
    m <- m[!duplicated(m$id) & !duplicated(m$id, fromLast=TRUE),] 
    GPS <- rep(NA, nrow(df2)) 
    GPS[m$id] <- m$GPS 
    return(GPS) 
} 
system.time(get.gps(df1, df2)) 
# user system elapsed 
# 16.197 0.561 17.583 

這是一個更加可以接受的運行 - 17秒而不是你估計在我的其他答案的評論90小時的時間!

1

我需要剛剛經歷每個df2元素的循環,實現邏輯檢查郵政編碼匹配和元件的範圍是合適的和偶數/奇數是正確的:

# Clean up data (character zip codes and fix the 7914 vs. 7941 issue in zip codes) 
df2<-data.frame(zipcode=c("7941AH", "7941AH", "7941AH", "7941AG","7941AG","7941AZ"), 
       housenum=c(18, 19, 50, 32, 104,11)) 
df1$Zipcode <- as.character(df1$Zipcode) 
df2$zipcode <- as.character(df2$zipcode) 

# Loop to compute the GPS values 
sapply(seq(nrow(df2)), function(x) { 
    m <- df2[x,] 
    matched <- df1$Zipcode == m$zipcode & 
    m$housenum >= df1$From & 
    m$housenum <= df1$To & 
    (df1$Type == "mixed" | 
    (df1$Type == "odd" & m$housenum %% 2 == 1) | 
    (df1$Type == "even" & m$housenum %% 2 == 0)) 
    if (sum(matched) != 1) { 
    return(NA) # No matches or multiple matches 
    } else { 
    return(df1$GPS[matched]) 
    } 
}) 
# [1] 12345 NA NA 54321 NA NA 

通過檢查,只有df2第一和第四元件通過在df1規則之一匹配。

+0

這工作正常!但是,我的實際數據集包含大約100萬個觀察值。我用proc.time()對500,1000和1500個觀測值執行了計時,如果我推斷這一點,則需要大約90個小時才能完成。任何想法爲什麼R在循環中遇到很多麻煩? – nsnvc

+0

@nsnvc有趣 - 你的問題沒有提到任何有關效率是一個問題的大數據集。你能否更新你的問題,關於你的數據集的詳細信息(郵政編碼的數量,'df1'的大小,'df2'的大小)? – josliber

+0

我已更新原始問題。順便說一句,我剛剛看到你是15.071x的開發人員之一:分析邊緣。多麼棒的課程!這是我轉換到R的原因。 – nsnvc