R 将数据帧展开为行对的组合

R 将数据帧展开为行对的组合,r,dataframe,R,Dataframe,我有一个数据框,它包含一个标识符/键列,后跟几行值列。 我希望通过将键列中唯一的条目对作为新行来扩展数据列,并使用对应行中条目的二进制操作来转换值列 例如 某些列可能包含或不包含缺少的值 我想要的是获取每对SYS条目,例如SYS1 SYS2,并对相应的值行计算一个二进制操作 例如,SYS1 SYS2 dE_water_freeSYS==SYS1-dE_water_freeSYS==SYS2。。。等 SYS1 SYS2 dE_water_free dE_wate

我有一个数据框,它包含一个标识符/键列,后跟几行值列。 我希望通过将键列中唯一的条目对作为新行来扩展数据列,并使用对应行中条目的二进制操作来转换值列

例如

某些列可能包含或不包含缺少的值

我想要的是获取每对SYS条目,例如SYS1 SYS2,并对相应的值行计算一个二进制操作 例如,SYS1 SYS2 dE_water_freeSYS==SYS1-dE_water_freeSYS==SYS2。。。等

        SYS1       SYS2   dE_water_free   dE_water_periodic   ...etc.
1 4NTJ_D294N  4NTJ_wild         114.489             105.610
2 4NTJ_D294N 4PXZ_D294N          -3.112               5.832
... etc.
我可以使用combn函数从SYSTEM列获取一个对数组,以形成SYS1和SYS2中的条目,但我不确定如何使用它来构建新的数据帧


我知道一种选择是使用mapply之类的工具,手工单独构建每一列,然后将它们全部粘贴到新的数据框中,但这似乎会很麻烦,而且速度很慢,应该有一个更自动的功能来完成,比如重塑、合并或重铸。。。但我似乎不知道该怎么做。

这里有两个解决方案,它们将数据的笛卡尔积/连接自身

在基R中,我考虑外部:

outer非常适合这种类型的问题:

de_wf <- with(Test_data, setNames(dE_water_free, SYS))
outer(de_wf, de_wf, `-`)

弗兰克的解决方案看起来简单多了。但这里有另一种合并方法

# Set Up
Test.data <- data.frame(
  Col1 = c(1,1,1,1,1,1),
  SYS = c("4NTJ_D294N",'4NTJ_wild',"4PXZ_D294N","4PXZ_wild","4PY0_D294N","4PY0_wild"),
  dE_water_free = c(-56.542,-171.031,-53.43,-59.99,-77.04,-79.08)
  )
基于dplyr的新思路

library("dplyr")
nuDat <- dplyr::left_join(
  dplyr::select(Test.data, Col1, SYS1 = SYS, dE_water_free1 = dE_water_free),
  dplyr::select(Test.data, Col1, SYS2 = SYS, dE_water_free2 = dE_water_free),
  by = "Col1"
  ) %>%
  dplyr::mutate(
    dE_water_free = dE_water_free1 - dE_water_free2
    ) %>%
  dplyr::filter(SYS1 != SYS2) %>%
  dplyr::select(
    SYS1, SYS2, dE_water_free
    )
你的梳子是个不错的选择。试试这个:

 combos<-combn(Test_data$SYS,2)
 water<-combn(Test_data$dE_water_free,2,FUN=function(x) x[1]-x[2])
 data.frame(SYS1=combos[1,],SYS2=combos[2,],water,stringsAsFactors=FALSE)
 #         SYS1       SYS2    water
 #1  4NTJ_D294N  4NTJ_wild  114.489
 #2  4NTJ_D294N 4PXZ_D294N   -3.112
 #3  4NTJ_D294N  4PXZ_wild    3.448
 #4  4NTJ_D294N 4PY0_D294N   20.498
 #5  4NTJ_D294N  4PY0_wild   22.538
 ........

松散相关:顺便说一句,如果您想要所有对,比如A、B和B、A,那么您需要在data.table包中使用expand.grid或CJ,而不是combn,我想。@BrodieG-Yup。你的设置名称是一个很好的捷径:嗯。。。我从CRAN下载了optiRum软件包,并尝试运行:res@wmsmith我只是复制粘贴了我链接到的答案中的函数,结果成功了。有趣的是,我在制作相关矩阵时可能必须记住这个命令。不幸的是,我需要对几个值列这样做,这样我才能绘制图,这样矩阵/网格方法可能对我不起作用。是否可以自动将其应用于原始数据帧中的每一个值列,或者我必须对每一列重复此操作?这在使用mapply包装时确实有效:>mapplyfunctiony combnTest_data[,y],2,FUN=functionx x[1]-x[2],cdE_water_free,dE_water_
de_wf <- with(Test_data, setNames(dE_water_free, SYS))
outer(de_wf, de_wf, `-`)
           4NTJ_D294N 4NTJ_wild 4PXZ_D294N 4PXZ_wild 4PY0_D294N 4PY0_wild
4NTJ_D294N      0.000   114.489     -3.112     3.448     20.498    22.538
4NTJ_wild    -114.489     0.000   -117.601  -111.041    -93.991   -91.951
4PXZ_D294N      3.112   117.601      0.000     6.560     23.610    25.650
4PXZ_wild      -3.448   111.041     -6.560     0.000     17.050    19.090
4PY0_D294N    -20.498    93.991    -23.610   -17.050      0.000     2.040
4PY0_wild     -22.538    91.951    -25.650   -19.090     -2.040     0.000
# Set Up
Test.data <- data.frame(
  Col1 = c(1,1,1,1,1,1),
  SYS = c("4NTJ_D294N",'4NTJ_wild',"4PXZ_D294N","4PXZ_wild","4PY0_D294N","4PY0_wild"),
  dE_water_free = c(-56.542,-171.031,-53.43,-59.99,-77.04,-79.08)
  )
library("dplyr")
nuDat <- dplyr::left_join(
  dplyr::select(Test.data, Col1, SYS1 = SYS, dE_water_free1 = dE_water_free),
  dplyr::select(Test.data, Col1, SYS2 = SYS, dE_water_free2 = dE_water_free),
  by = "Col1"
  ) %>%
  dplyr::mutate(
    dE_water_free = dE_water_free1 - dE_water_free2
    ) %>%
  dplyr::filter(SYS1 != SYS2) %>%
  dplyr::select(
    SYS1, SYS2, dE_water_free
    )
 combos<-combn(Test_data$SYS,2)
 water<-combn(Test_data$dE_water_free,2,FUN=function(x) x[1]-x[2])
 data.frame(SYS1=combos[1,],SYS2=combos[2,],water,stringsAsFactors=FALSE)
 #         SYS1       SYS2    water
 #1  4NTJ_D294N  4NTJ_wild  114.489
 #2  4NTJ_D294N 4PXZ_D294N   -3.112
 #3  4NTJ_D294N  4PXZ_wild    3.448
 #4  4NTJ_D294N 4PY0_D294N   20.498
 #5  4NTJ_D294N  4PY0_wild   22.538
 ........