将函数应用于除当前行之外的所有行 (dplyr)

Jon*_*den 7 r dplyr

dplyr到目前为止,我正在学习R 包并且非常喜欢它。我需要做的一件事是创建一个新列,其每一行的值是将函数应用于除当前行以外的所有行(可能按组划分)的结果,但我想不出一种简洁的方法.

一个人为的例子是

library(datasets)
library(dplyr)

data(mtcars)
x <- mtcars %>% mutate(name=rownames(mtcars)) %>% filter(cyl==4) %>% select(name,cyl,mpg)

# This is what I want to do more elegantly
x$othermpg <- NA
for (i in 1:nrow(x))
    x$othermpg[i] <- mean(x$mpg[-i])
Run Code Online (Sandbox Code Playgroud)

此处,该othermpg列获取mpg除当前行中的汽车之外的所有汽车的平均值。

请问有人可以帮忙吗?

akr*_*run 3

这可以在data.table

 library(data.table)
 setDT(x)[, N:= 1:.N][, othermpg2:=mean(x[N!= .BY, mpg]), by=N][,N:=NULL]
  x
  #             name cyl  mpg othermpg othermpg2
  #1:     Datsun 710   4 22.8    27.05     27.05
  #2:      Merc 240D   4 24.4    26.89     26.89
  #3:       Merc 230   4 22.8    27.05     27.05
  #4:       Fiat 128   4 32.4    26.09     26.09
  #5:    Honda Civic   4 30.4    26.29     26.29
  #6: Toyota Corolla   4 33.9    25.94     25.94
  #7:  Toyota Corona   4 21.5    27.18     27.18
  #8:      Fiat X1-9   4 27.3    26.60     26.60
  #9:  Porsche 914-2   4 26.0    26.73     26.73
 #10:   Lotus Europa   4 30.4    26.29     26.29
 #11:     Volvo 142E   4 21.4    27.19     27.19
Run Code Online (Sandbox Code Playgroud)
  • 这个想法是首先创建一个行索引/列N:=1:.N
  • 根据该索引进行分组by=N]
  • x[N!= .BY, mpg]mpg给出不等于分组变量的行
  • 做平均
  • N:=NULL由于不需要 N,因此该列被删除。

或者你可以尝试(灵感来自@thelatemail的回答)

 setDT(x)[, N:=1:.N]
 setkey(x, N)
 x[,othermpg2 := mean(x[!.BY, mpg]), by=N][,N:=NULL]
Run Code Online (Sandbox Code Playgroud)

或者不创建N(来自@Jon Clayden 的评论)

 setDT(x)[, othermpg2:=mean(x[name!=.BY,mpg]), by=name]
Run Code Online (Sandbox Code Playgroud)

使用dplyr,这似乎有效

x %>% 
mutate(N=1:n()) %>% 
do( data.frame(.,othermpg2=sapply(.$N, function(i) mean(.$mpg[!.$N %in% i]))))
  #             name cyl  mpg othermpg  N othermpg2
  #1      Datsun 710   4 22.8    27.05  1     27.05
  #2       Merc 240D   4 24.4    26.89  2     26.89
  #3        Merc 230   4 22.8    27.05  3     27.05
  #4        Fiat 128   4 32.4    26.09  4     26.09
  #5     Honda Civic   4 30.4    26.29  5     26.29
  #6  Toyota Corolla   4 33.9    25.94  6     25.94
  #7   Toyota Corona   4 21.5    27.18  7     27.18
  #8       Fiat X1-9   4 27.3    26.60  8     26.60
  #9   Porsche 914-2   4 26.0    26.73  9     26.73
  #10   Lotus Europa   4 30.4    26.29 10     26.29
  #11     Volvo 142E   4 21.4    27.19 11     27.19
Run Code Online (Sandbox Code Playgroud)