[英]Apply User-Defined Function to Specific Dataframe Columns
I have seen the question here R apply user define function on data frame columns but mine is a little different... 我在这里看到的问题是R在数据框列上应用了用户定义函数,但是我的有点不同...
I would like to pass specific columns of my dataframe to a function, then return the result of that function to a new column of my dataframe. 我想将数据框的特定列传递给函数,然后将该函数的结果返回到数据框的新列。
Basically, I have a dataframe like this: 基本上,我有一个像这样的数据框:
df.latitude1
df.longitude1
df.latitude2
df.longitude2
Then I have a method getDistance(lat1, lng1, lat2, lng2)
and I would like to return the result of that computation into a new column in my dataframe called distance
. 然后,我有一个方法
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")
Your best bet is probably to use a vectorized function and compute the distances for all pairs of points at the same time. 最好的选择可能是使用向量化函数并同时计算所有成对点的距离。 For instance, you could use the
distHaversine
function from the geosphere
package to do the calculation in one shot: 例如,你可以使用
distHaversine
功能从geosphere
包做计算在一个镜头:
# 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
If you were going to use a function from the apply
family, you would probably loop through the rows of your data frame, computing the distances one at a time. 如果要使用
apply
系列中的函数,则可能会遍历数据框的行,一次计算一次距离。 While this will give the same answer, it will be much slower: 虽然这将给出相同的答案,但速度会慢得多:
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
The reason for the 100x slowdown is that you can't take advantage of vectorization if you perform the distance computation one row at a time. 速度降低100倍的原因是,如果一次执行一行距离计算,则无法利用向量化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.