zac*_*ach 31 r apply dataframe
我有一个dataframe,我想应用一个取三列值的函数,并计算三个值之间的最小差异.
#dataset
df <- data.frame(a= sample(1:100, 10),b = sample(1:100, 10),c= sample(1:100, 10))
#function
minimum_distance <- function(a,b,c)
{
dist1 <- abs(a-b)
dist2 <- abs(a-c)
dist3 <- abs(b-c)
return(min(dist1,dist2,dist3))
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找类似的东西:
df$distance <- sapply(df, function(x) minimum_distance(x$a,x$b,x$c) )
## errormessage
Error in x$a : $ operator is invalid for atomic vectors
Run Code Online (Sandbox Code Playgroud)
虽然我可以使用ddply:
df2 <- ddply(df,.(a),function(r) {data.frame(min_distance=minimum_distance(r$a,r$b, r$c))}, .drop=FALSE)
Run Code Online (Sandbox Code Playgroud)
这并没有保留所有列.有什么建议?
编辑:我最终使用:
df$distance <- mapply(minimum_distance, df$a, df$b, df$c)
Run Code Online (Sandbox Code Playgroud)
geo*_*try 49
尝试mapply():
qq <- mapply(minimum_distance, df$a, df$b, df$c)
Run Code Online (Sandbox Code Playgroud)
试试这个:
do.call("mapply", c(list(minimum_distance), df))
Run Code Online (Sandbox Code Playgroud)
但你可以写矢量化版本:
pminimum_distance <- function(a,b,c)
{
dist1 <- abs(a-b)
dist2 <- abs(a-c)
dist3 <- abs(b-c)
return(pmin(dist1,dist2,dist3))
}
pminimum_distance(df$a, df$b, df$c)
# or
do.call("pminimum_distance", df)
Run Code Online (Sandbox Code Playgroud)
我知道这已经得到了回答,但我实际上采用了一种不同的方法,它采用了任意数量的列,并且使用外部方法更具一般性:
vdiff <- function(x){
y <- outer(x, x, "-")
min(abs(y[lower.tri(y)]))
}
apply(df, 1, vdiff)
Run Code Online (Sandbox Code Playgroud)
我认为这有点清洁和灵活.
编辑:Per zach的评论我提出了这个更正式的函数,它可以处理非数字列的数据框,也可以删除它们并仅对数字列起作用.
cdif <- function(dataframe){
df <- dataframe[, sapply(dataframe, is.numeric)]
vdiff <- function(x){
y <- outer(x, x, "-")
min(abs(y[lower.tri(y)]))
}
return(apply(df, 1, vdiff))
}
#TEST it out
set.seed(10)
(df <- data.frame(a = sample(1:100, 10), b = sample(1:100, 10),
c = sample(1:100, 10), d = LETTERS[1:10]))
cdif(df)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
35496 次 |
| 最近记录: |