R成对运算

R成对运算,r,R,我有一个数据帧,想对它执行一些特定的操作 dat <- data.frame(Name = LETTERS[1:3], Val1 = rnorm(3), Val2 = rnorm(3)) # > dat # Name Val1 Val2 # 1 A -1.055050 0.4499766 # 2 B 0.414994 -0.5999369 # 3 C -1.311

我有一个数据帧,想对它执行一些特定的操作

dat <- data.frame(Name = LETTERS[1:3],
                  Val1 = rnorm(3),
                  Val2 = rnorm(3))

# > dat
#   Name      Val1       Val2
# 1    A -1.055050  0.4499766
# 2    B  0.414994 -0.5999369
# 3    C -1.311374 -0.3967634

其中,
是实际结果。

combn
是这里的工作马,可用于生成独特的成对组合:

combn(as.character(dat$Name), 2, simplify=FALSE)
#[[1]]
#[1] "A" "B"
#
#[[2]]
#[1] "A" "C"
#
#[[3]]
#[1] "B" "C"
您还可以将这些成对组合的结果传递给函数,然后:

# set.seed(1)
##for reproducibility

combn(
  as.character(dat$Name),
  2,
  FUN=function(x) do.call(`-`, dat[dat$Name == x[1], -1] / dat[dat$Name == x[2], -1])
)
#[1] -8.2526585  2.6940335  0.1818427

AB3
#[1] -8.252659
AC3
#[1] 2.694033
BC3
#[1] 0.1818427

combn
在这里是一个工作平台,可用于生成独特的成对组合:

combn(as.character(dat$Name), 2, simplify=FALSE)
#[[1]]
#[1] "A" "B"
#
#[[2]]
#[1] "A" "C"
#
#[[3]]
#[1] "B" "C"
您还可以将这些成对组合的结果传递给函数,然后:

# set.seed(1)
##for reproducibility

combn(
  as.character(dat$Name),
  2,
  FUN=function(x) do.call(`-`, dat[dat$Name == x[1], -1] / dat[dat$Name == x[2], -1])
)
#[1] -8.2526585  2.6940335  0.1818427

AB3
#[1] -8.252659
AC3
#[1] 2.694033
BC3
#[1] 0.1818427

使用data.table,您可以使用以下代码执行此操作:

library(data.table)
dat <- data.table(Region = rep(LETTERS[24:26], each=3),
                   Name = rep(LETTERS[1:3], 3),
                   Val1 = rep(rnorm(3), 3),
                   Val2 = rep(rnorm(3), 3))
dat2 <- merge(dat, dat, by="Region", allow.cartesian = T)[Name.x < Name.y]
dat2[, Val1Ratio := Val1.x / Val1.y]
dat2[, Val2Ratio := Val2.x / Val2.y]
dat2[, Diff := Val1Ratio - Val2Ratio]
库(data.table)

dat对于data.table,您可以使用以下代码执行此操作:

library(data.table)
dat <- data.table(Region = rep(LETTERS[24:26], each=3),
                   Name = rep(LETTERS[1:3], 3),
                   Val1 = rep(rnorm(3), 3),
                   Val2 = rep(rnorm(3), 3))
dat2 <- merge(dat, dat, by="Region", allow.cartesian = T)[Name.x < Name.y]
dat2[, Val1Ratio := Val1.x / Val1.y]
dat2[, Val2Ratio := Val2.x / Val2.y]
dat2[, Diff := Val1Ratio - Val2Ratio]
库(data.table)

dat@最近的邮件的回答对我问题的第一部分很有效。我最初试图将以下信息作为附加编辑添加到他们的答案中,以解决我问题的第二部分。此编辑被拒绝,因此我将其作为答案:


使用@thelatemail的答案解决问题的第二部分(与dat2相关并按地区分组)的一种方法如下:

library("dplyr")
Regions <- unique(dat2$Region)
out <- data.frame(Region = Regions, AB3 = NA, AC3 = NA, BC3 = NA)
for (i in 1:length(Regions)){

  dat2temp <- dat2 %>% filter(Region==Regions[i])

  out[i,2:4] <-   combn(
    as.character(dat2temp$Name),
    2,
    FUN = function(x) do.call(`-`, dat2temp[dat2temp$Name == x[1], -(1:2)] / dat2temp[dat2temp$Name == x[2], -(1:2)])
    )
}

> out
#   Region       AB3        AC3       BC3
# 1      X -4.368693 -0.4772375 0.3004291
# 2      Y -4.368693 -0.4772375 0.3004291
# 3      Z -4.368693 -0.4772375 0.3004291
库(“dplyr”)

地区@最近的邮件对我问题的第一部分回答得很好。我最初试图将以下信息作为附加编辑添加到他们的答案中,以解决我问题的第二部分。此编辑被拒绝,因此我将其作为答案:


使用@thelatemail的答案解决问题的第二部分(与dat2相关并按地区分组)的一种方法如下:

library("dplyr")
Regions <- unique(dat2$Region)
out <- data.frame(Region = Regions, AB3 = NA, AC3 = NA, BC3 = NA)
for (i in 1:length(Regions)){

  dat2temp <- dat2 %>% filter(Region==Regions[i])

  out[i,2:4] <-   combn(
    as.character(dat2temp$Name),
    2,
    FUN = function(x) do.call(`-`, dat2temp[dat2temp$Name == x[1], -(1:2)] / dat2temp[dat2temp$Name == x[2], -(1:2)])
    )
}

> out
#   Region       AB3        AC3       BC3
# 1      X -4.368693 -0.4772375 0.3004291
# 2      Y -4.368693 -0.4772375 0.3004291
# 3      Z -4.368693 -0.4772375 0.3004291
库(“dplyr”)

有多种方法可以做到这一点,但一种相当有效的方法是迭代
combn
调用,例如
sapply(combn(nrow(dat),2,simplify=FALSE),函数(i){dat[i[1],'Val1']/dat[i[2],'Val1']}
@alistaire,使用
sapply(combn(nrow(dat),2,simplify=FALSE),函数(i){dat[i[1],'Val1']/dat[i[2],'Val1']-dat[i[1],'Val2']/dat[i[2],'Val2']}可以扩展到所有3点。
实现这一点的方法有很多种,但一种相当有效的方法是在
combn
调用中迭代,例如
sapply(combn(nrow(dat),2,simplify=FALSE),函数(i){dat[i[1],'Val1']/dat[i[2],'Val1']}
@alistaire您的评论很适合做其中一点,并且可以使用
sapply(combn(nrow(dat),2,simplify=FALSE),函数(i){dat[i[1],'Val1']/dat[i[2],'Val1']-dat[i[i[1],'Val2']/dat[i[2],'Val2'],这很好,完成了第一个目标。您知道使用
dat2
并按区域分组的方法来处理第二部分吗?谢谢,这很好,实现了第一个目标。您知道使用
dat2
和按区域分组的方法来接近第二部分吗?
library("dplyr")
Regions <- unique(dat2$Region)
out <- data.frame(Region = Regions, AB3 = NA, AC3 = NA, BC3 = NA)
for (i in 1:length(Regions)){

  dat2temp <- dat2 %>% filter(Region==Regions[i])

  out[i,2:4] <-   combn(
    as.character(dat2temp$Name),
    2,
    FUN = function(x) do.call(`-`, dat2temp[dat2temp$Name == x[1], -(1:2)] / dat2temp[dat2temp$Name == x[2], -(1:2)])
    )
}

> out
#   Region       AB3        AC3       BC3
# 1      X -4.368693 -0.4772375 0.3004291
# 2      Y -4.368693 -0.4772375 0.3004291
# 3      Z -4.368693 -0.4772375 0.3004291