簡體   English   中英

使用多列作為 sapply 的變量

[英]use multiple columns as variables with sapply

我有一個dataframe ,我想應用一個 function,它采用三列的值並計算這三個值之間的最小差值。

#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))
}

我正在尋找類似的東西:

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

雖然我可以使用 ddply:

df2 <- ddply(df,.(a),function(r) {data.frame(min_distance=minimum_distance(r$a,r$b, r$c))}, .drop=FALSE)

這不會保留所有列。 有什么建議么?

編輯:我最終使用:

df$distance <- mapply(minimum_distance, df$a, df$b, df$c)

嘗試映射():

qq <- mapply(minimum_distance, df$a, df$b, df$c)

試試這個:

do.call("mapply", c(list(minimum_distance), df))

但您可以編寫矢量化版本:

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)

我知道這已經得到解答,但實際上我會采用一種不同的方法,該方法采用任意數量的列,並且使用外部方法更具有普遍性:

vdiff <- function(x){
    y <- outer(x, x, "-")
    min(abs(y[lower.tri(y)]))
}

apply(df, 1, vdiff)

我認為這有點清潔和靈活。

編輯:根據 zach 的評論,我提出了這個更正式的 function,它適用於具有非數字列的數據框,也通過刪除它們並僅作用於數字列。

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)

最好寫一個 function 然后在向量上使用 mapply :

 f1 <- function(a,b,c){
 d =abs(a-b)
 e =abs(b-c)
 f= abs(c-a)
 return(pmin(d,e,f))
 }

 qq <- mapply(f1, df$a, df$b, df$c)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM