【问题标题】:Assigning Subgroups in Data R在数据 R 中分配子组
【发布时间】:2020-01-04 16:23:59
【问题描述】:

我知道如何在 R 中做一些基本的事情,但我还是个新手。我也可能问了一个非常多余的问题(但我不知道如何将其输入谷歌以便找到正确的点击)。

我得到了如下的点击:

Assign value to group based on condition in column

R - Group by variable and then assign a unique ID

我想将子组分配到组中,并从中创建一个新列。 我有如下数据:

数据框:

ID    SubID    Values
1     15       0.5
1     15       0.2
2     13       0.1
2     13       0
1     14       0.3
1     14       0.3
2     10       0.2
2     10       1.6
6     31       0.7
6     31       1.0

新数据框:

ID    SubID    Values   groups
1     15       0.5      2
1     15       0.2      2
2     13       0.1      2
2     13       0        2
1     14       0.3      1
1     14       0.3      1
2     10       0.2      1
2     10       1.6      1
6     31       0.7      1
6     31       1.0      1

我在 R 中尝试了以下方法,但没有得到想要的结果:

newdataframe$groups <- dataframe %>% group_indices(,dataframe$ID, dataframe$SubID)
newdataframe<- dataframe %>% group_by(ID, SubID) %>% mutate(groups=group_indices(,dataframe$ID, dataframe$SubID))

我不确定如何在 R 中构建问题。我想按 ID 和 SubID 分组,然后分配按 ID 分组的子组并重置每个 ID 的分组计数。

任何帮助将不胜感激。

【问题讨论】:

  • 我认为您不应该直接致电group_indices。您能描述一下您是如何确定哪些行进入哪些组的吗?
  • 每个 ID 都有一定数量的 SubID。每个 SubID 可能出现多次。我想对每个组的 SubID 进行分组。这是为了比较所有ID SubIDs group 1's together, group 2's together etc. 另外,为什么直接调用 group_indices 不合适?
  • 什么是分组规则???学习用自然语言解释。一个例子通常是模棱两可的。正如你最肯定的那样。
  • 分组在 ID 和 SubID 上。我想对子 ID 进行排名(或将分配为组的唯一子 ID 计数)。这样每个ID的第一个SubID属于group 1,每个ID的第二个SubID属于group 2,以此类推
  • 顺便说一句:ENZSIO,我找到了一个很好的反例来反驳我不直接调用group_indices (stackoverflow.com/a/57808024) 的声明。我仍然认为它不一定正确here,但现在我会质疑我的假设,即它的主要用途是在幕后。干杯。

标签: r dataframe group-by dplyr data-manipulation


【解决方案1】:

有多种方法可以做到这一点,一种方法是 group_by ID 并为每个 SubID 创建一个唯一编号,方法是将其转换为 factor 然后再转换为整数。

library(dplyr)

df %>%
  group_by(ID) %>%
  mutate(groups = as.integer(factor(SubID)))

#     ID SubID Values groups
#   <int> <int>  <dbl>  <int>
# 1     1    15    0.5      2
# 2     1    15    0.2      2
# 3     2    13    0.1      2
# 4     2    13    0        2
# 5     1    14    0.3      1
# 6     1    14    0.3      1
# 7     2    10    0.2      1
# 8     2    10    1.6      1
# 9     6    31    0.7      1
#10     6    31    1        1

在base R中,我们可以使用ave,类似的逻辑

df$groups <- with(df, ave(SubID, ID, FUN = factor))

【讨论】:

  • df$groups
  • @ENZSIO 它已经将每个 ID 的计数重置为 1,对吧?
  • 我对我的数据进行了尝试,但它计数而不是重置(我的 ID 是数字,我的子 ID 是 )。我提供的数据集是一个例子(不能发布任何真实数据)。
  • @ENZSIO 你能试试dplyr 的替代方法,看看它是否返回相同的结果吗?
  • 我都试过了。第一个为组创建了唯一的 ID。替代方案更接近了,但仍然没有。我只想比较属于第 1 组的 ID 的 SubID,或者比较所有第 2 组。
【解决方案2】:

这是一种替代方法,它使用 data.table 包中的 rleid() 函数。 rleid() 生成一个游程类型 id 列。

根据预期结果,OP 期望 SubId 按值顺序而不是按出现顺序编号。因此,我们需要拨打arrange()

library(dplyr)
df %>% 
  group_by(ID) %>% 
  arrange(SubID) %>% 
  mutate(groups = data.table::rleid(SubID))
      ID SubID Values groups
   <int> <int>  <dbl>  <int>
 1     2    10    0.2      1
 2     2    10    1.6      1
 3     2    13    0.1      2
 4     2    13    0        2
 5     1    14    0.3      1
 6     1    14    0.3      1
 7     1    15    0.5      2
 8     1    15    0.2      2
 9     6    31    0.7      1
10     6    31    1        1

请注意,行顺序已更改。

顺便说一句:使用data.table,代码不那么冗长,并且保持原始行顺序:

library(data.table)
setDT(df)[order(ID, SubID), groups := rleid(SubID), by = ID][]
    ID SubID Values groups
 1:  1    15    0.5      2
 2:  1    15    0.2      2
 3:  2    13    0.1      2
 4:  2    13    0.0      2
 5:  1    14    0.3      1
 6:  1    14    0.3      1
 7:  2    10    0.2      1
 8:  2    10    1.6      1
 9:  6    31    0.7      1
10:  6    31    1.0      1

【讨论】:

  • 谢谢 Uwe!第一个示例稍微有效,但出于某种奇怪的原因将所有内容都分配给了 1。使用 data.table 的第二个示例成功了:setDT(df)[order(ID, SubID), groups := rleid(SubID), by = ID][]。我今天将阅读 data.table 文档并了解它。谢谢你:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-18
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多