如何使用 dplyr 在行组之间进行划分?

Posted

技术标签:

【中文标题】如何使用 dplyr 在行组之间进行划分?【英文标题】:How to divide between groups of rows using dplyr? 【发布时间】:2016-09-23 16:44:51 【问题描述】:

我有这个数据框:

x <- data.frame(
    name = rep(letters[1:4], each = 2),
    condition = rep(c("A", "B"), times = 4),
    value = c(2,10,4,20,8,40,20,100)
) 
#   name condition value
# 1    a         A     2
# 2    a         B    10
# 3    b         A     4
# 4    b         B    20
# 5    c         A     8
# 6    c         B    40
# 7    d         A    20
# 8    d         B   100

我想按名称分组并将condition == "B" 行的值与condition == "A" 行的值相除,得到这个:

data.frame(
    name = letters[1:4],
    value = c(5,5,5,5)
)
#   name value
# 1    a     5
# 2    b     5
# 3    c     5
# 4    d     5

我知道这样的事情可以让我非常接近:

x$value[which(x$condition == "B")]/x$value[which(x$condition == "A")]

但我想知道是否有一种简单的方法可以使用 dplyr 来做到这一点(我的数据框是一个玩具示例,我通过链接多个 group_bysummarise 调用来实现它)。

【问题讨论】:

【参考方案1】:

使用data.table,将'data.frame'转换为'data.table'(setDT(x)),按'name'分组,我们将'value'对应'B'条件除以那些对应的条件到'A''条件'。

library(data.table)
setDT(x)[,.(value = value[condition=="B"]/value[condition=="A"]) , name]
#    name value
#1:    a     5
#2:    b     5
#3:    c     5
#4:    d     5

或从“长”重塑为“宽”,并将“B”列除以“A”。

dcast(setDT(x), name~condition, value.var='value')[, .(name, value = B/A)]

【讨论】:

@user5249203 也许你的意思是 Map 或者你想除以 x[-1]/x[-length(x)] 之类的东西 @user5249203 在此解决方案的上下文中,您的评论对我来说并不清楚,因为我们正在对每一行进行条件检查,即相同。你的意思是condtion == 'a',条件=='b',条件=='a','等等。在这种情况下,需要MapMap(function(x, y) value[condtion == x]/value[condition == y], yourfirstvec_orcol, yoursecondvec) 将尝试发布问题。【参考方案2】:

我会使用来自tidyrspread

library(dplyr)
library(tidyr)

x %>%
  spread(condition, value) %>%
  mutate(value = B/A)

  name  A   B value
1    a  2  10     5
2    b  4  20     5
3    c  8  40     5
4    d 20 100     5

然后您可以使用select(-A, -B) 删除多余的列。

【讨论】:

【参考方案3】:

试试:

x %>% 
  group_by(name) %>%
  summarise(value = value[condition == "B"] / value[condition == "A"])

这给出了:

#Source: local data frame [4 x 2]
#
#    name value
#  (fctr) (dbl)
#1      a     5
#2      b     5
#3      c     5
#4      d     5

【讨论】:

我有和上面一样的数据,唯一的区别是有时“条件”列没有“A”或“B”,所以有时没有分母或分子。我想删除这些行并继续划分。你有什么想法吗? @vicky 只是预先过滤它们? x %>% 过滤器(条件 %in% c("A", "B"))

以上是关于如何使用 dplyr 在行组之间进行划分?的主要内容,如果未能解决你的问题,请参考以下文章

如何按组进行汇总并使用R中的dplyr获取总体数据集的摘要

如何按组加速子集

用dplyr汇总后如何执行计算?

如何通过使用 dplyr 或其他包在 R 中具有最小值和最大值的查询来实现组?

如何使用 R 和 dplyr 中连续的元素执行 group_by

如何使用透明间距/边框在行之间留出空间 - HTML/CSS