【问题标题】:Create column based on distinctive sets of multiple row values基于不同的多行值集创建列
【发布时间】:2022-01-26 21:49:38
【问题描述】:

我想根据另一列中的行值识别一列中唯一的行值集,以最终在数据框中创建一个新列。下图说明了我的问题和预期结果(即expected_outcome 列)。

例如:

  • 前 3 行在 trial 列中具有值 T1,在 group 列中具有值 D1, D2, D3

  • 接下来的 3 行在 trial 列中具有值 T3,在 group 列中具有值 D3, D2, D1

因为集合 D1, D2, D3D3, D2, D1 具有相同的包含,我希望所有 6 行在列 expected_outcome 中具有相同的值。

我的数据远比这复杂。我可能必须对超过 2 列进行分组。所以,我更喜欢这个问题的通用解决方案。下面是图中的数据。

test_data <- data.frame(
  trial            = c("T1", "T1", "T1", "T3", "T3", "T3", "T5", "T5", "T6", "T6", "T6"),
  group            = c("D1", "D2", "D3", "D3", "D2", "D1", "D1", "D3", "D1", "D3", "D2")
)

【问题讨论】:

  • 那么当两个试验包含完全相同的组时,expected_outcome 是否相同?
  • T6 也有 D1 D3 D2?
  • 是的@tavdp!但我也需要分组来考虑组列中的行值序列。
  • @TarJae,这是正确的!最后一行应该是 T7 而不是 T6。我更新了图片。

标签: r dataframe grouping


【解决方案1】:

你可以通过tidyverse做这样的事情。

library(tidyverse)

test_data %>%
  group_by(trial) %>%
  summarize(type = paste(sort(unique(group)), collapse = ", "), group) %>%
  group_by(type) %>%
  mutate(expected_outcome = cur_group_id()) %>%
  ungroup() %>%
  dplyr::select(-"type")

输出

# A tibble: 11 × 3
   trial group expected_outcome
   <chr> <chr>            <int>
 1 T1    D1                   1
 2 T1    D2                   1
 3 T1    D3                   1
 4 T3    D3                   1
 5 T3    D2                   1
 6 T3    D1                   1
 7 T5    D1                   2
 8 T5    D3                   2
 9 T6    D1                   1
10 T6    D3                   1
11 T6    D2                   1

数据

test_data <-
  structure(list(
    trial = c("T1", "T1", "T1", "T3", "T3", "T3",
              "T5", "T5", "T6", "T6", "T6"),
    group = c("D1", "D2", "D3", "D3",
              "D2", "D1", "D1", "D3", "D1", "D3", "D2")
  ),
  class = "data.frame",
  row.names = c(NA,-11L))

【讨论】:

    【解决方案2】:

    我认为您专栏中的最后一个trial 应该是T7

    library(dplyr)
    
    test_data %>% 
      arrange(across(everything())) %>% 
      group_by(trial) %>% 
      mutate(expected_outcome = toString(group)) %>%
      group_by(expected_outcome) %>% 
      mutate(expected_outcome = cur_group_id())
    
        trial group expected_outcome
       <chr> <chr>            <int>
     1 T1    D1                   1
     2 T1    D2                   1
     3 T1    D3                   1
     4 T3    D1                   1
     5 T3    D2                   1
     6 T3    D3                   1
     7 T5    D1                   2
     8 T5    D3                   2
     9 T6    D1                   2
    10 T6    D3                   2
    11 T7    D2                   3
    

    数据:

    test_data <- structure(list(trial = c("T1", "T1", "T1", "T3", "T3", "T3", 
    "T5", "T5", "T6", "T6", "T7"), group = c("D1", "D2", "D3", "D3", 
    "D2", "D1", "D1", "D3", "D1", "D3", "D2")), class = "data.frame", row.names = c(NA, 
    -11L))
    

    【讨论】:

    • 三个答案中的每一个都解决了我的问题,但我发现这个真的很优雅!
    【解决方案3】:

    注意:此答案基于编辑 OP 之前的 original problem,其中组必须自行识别,没有错误的 'trial' 列。

    factorize 组列,并使用ave 计算每个组中duplicateds 的cumsum。然后,在出现偶数的地方,cumsum 的差等于1

    (test_data <- within(test_data, { 
                        group_int <- as.integer(as.factor(group))
                        group_2 <- ave(group_int, group_int, FUN=\(x) 
                                       cumsum(duplicated(x)))
                        expected_outcome <- cumsum(c(1, diff(group_2 %% 2 == 0)) == 1)
                        rm(group_int, group_2)
    }))
    #    trial group expected_outcome
    # 1     T1    D1                1
    # 2     T1    D2                1
    # 3     T1    D3                1
    # 4     T3    D3                1
    # 5     T3    D2                1
    # 6     T3    D1                1
    # 7     T5    D1                2
    # 8     T5    D3                2
    # 9     T6    D1                2
    # 10    T6    D3                2
    # 11    T6    D2                3
    

    注意: R >= 4.1


    数据:

    test_data <- structure(list(trial = c("T1", "T1", "T1", "T3", "T3", "T3", 
    "T5", "T5", "T6", "T6", "T6"), group = c("D1", "D2", "D3", "D3", 
    "D2", "D1", "D1", "D3", "D1", "D3", "D2"), expected_outcome = c(1L, 
    1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L)), row.names = c(NA, -11L
    ), class = "data.frame")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-14
      • 1970-01-01
      • 1970-01-01
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多