【问题标题】:Apply User-Defined Function to Specific Dataframe Columns将用户定义的函数应用于特定的数据框列
【发布时间】:2015-06-01 21:57:26
【问题描述】:

我在这里看到了R apply user define function on data frame columns 的问题,但我的问题有点不同......

我想将我的数据框的特定列传递给一个函数,然后将该函数的结果返回到我的数据框的一个新列。

基本上,我有一个这样的数据框:

df.latitude1
df.longitude1
df.latitude2
df.longitude2

然后我有一个方法getDistance(lat1, lng1, lat2, lng2),我想将该计算的结果返回到我的数据框中名为distance 的新列中。

更新

> asn$geoDistance <- distHaversine(asn[,c("homeLocationGeoLat", "homeLocationGeoLng")], dat[,c("hostLocationGeoLat", "hostLocationGeoLng")])
Error in .pointsToMatrix(p1) : latitude < -90
> asn$homeLocationGeoLat[asn$homeLocationGeoLat < -90]
  [1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
 [40] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
 [79] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[118] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[157] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[196] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[235] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[274] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[313] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[352] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[391] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[430] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[469] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[508] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[547] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
> asn$hostLocationGeoLat[asn$hostLocationGeoLat < -90]
  [1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
 [40] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
 [79] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[118] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[157] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[196] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[235] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[274] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[313] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[352] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[391] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[430] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[469] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[508] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[547] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[586] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[625] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[664] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[703] NA NA NA NA NA NA NA NA NA
> newDf <- asn[, c('durationDays', 'homeLocationGeoLat', 'homeLocationGeoLng', 'hostLocationGeoLat', 'hostLocationGeoLng')]
> dput(head(newDf))
structure(list(durationDays = c(0, 0, 180, 0, 365, 0), homeLocationGeoLat = c(-23.5489433, 
1.2800945, 12.9715987, 25.7889689, 49.3063689, 25.271139), homeLocationGeoLng = c(-46.6388182, 
103.8509491, 77.5945627, -80.2264393, 8.6427693, 55.307485), 
    hostLocationGeoLat = c(37.4418834, 49.2774456, 52.3905689, 
    49.3063689, 53.3498053, 37.4418834), hostLocationGeoLng = c(-122.1430195, 
    7.1118995, 13.0644729, 8.6427693, -6.2603097, -122.1430195
    )), .Names = c("durationDays", "homeLocationGeoLat", "homeLocationGeoLng", 
"hostLocationGeoLat", "hostLocationGeoLng"), row.names = c(NA, 
6L), class = "data.frame")

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    您最好的选择可能是使用矢量化函数并同时计算所有点对的距离。例如,您可以使用 geosphere 包中的 distHaversine 函数一次性完成计算:

    # 10000 points
    set.seed(144)
    dat <- data.frame(lat1=runif(10000, 10, 20), lng1=runif(10000, 10, 20),
                      lat2=runif(10000, 10, 20), lng2=runif(10000, 10, 20))
    
    # Get all distances
    library(geosphere)
    dat$distance <- distHaversine(dat[,c("lng1", "lat1")], dat[,c("lng2", "lat2")])
    head(dat$distance)
    # [1] 293912.3 332583.2 870767.8 167362.9 371920.6 659368.1
    

    如果您要使用 apply 系列中的函数,您可能会遍历数据框的行,一次计算一个距离。虽然这会给出相同的答案,但速度会慢得多:

    all.equal(distHaversine(dat[,c("lng1", "lat1")], dat[,c("lng2", "lat2")]),
              apply(dat, 1, function(x) distHaversine(x[c("lng1", "lat1")], x[c("lng2", "lat2")])))
    # [1] TRUE
    system.time(distHaversine(dat[,c("lng1", "lat1")], dat[,c("lng2", "lat2")]))
    #    user  system elapsed 
    #   0.005   0.001   0.008 
    system.time(apply(dat, 1, function(x) distHaversine(x[c("lng1", "lat1")], x[c("lng2", "lat2")])))
    #    user  system elapsed 
    #   0.887   0.007   0.895 
    

    100 倍减速的原因是,如果一次执行一行距离计算,则无法利用矢量化。

    【讨论】:

      猜你喜欢
      • 2021-09-06
      • 2018-11-10
      • 2021-09-14
      • 2020-10-01
      • 2020-11-11
      • 1970-01-01
      • 2020-10-28
      • 2023-03-02
      • 2021-09-20
      相关资源
      最近更新 更多