根据不同的多行值集创建列
Create column based on distinctive sets of multiple row values
我想根据另一列中的行值识别一列中唯一的行值集,以最终在数据框中创建一个新列。下图说明了我的问题和预期结果(即 expected_outcome
列)。
例如:
前 3 行在 trial
列中具有值 T1
,在 group
列中具有值 D1, D2, D3
。
接下来的 3 行在 trial
列中具有值 T3
,在 group
.[=24= 列中具有值 D3, D2, D1
]
因为集合 D1, D2, D3
与 D3, 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")
)
您可以通过 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))
我认为您专栏中的最后一个 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))
注意:此答案基于编辑 OP 之前的 original problem,其中组必须由他们自己识别,没有错误的 'trial'
列.
factor
化组列,并使用 ave
计算每个组中 duplicated
的 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")
我想根据另一列中的行值识别一列中唯一的行值集,以最终在数据框中创建一个新列。下图说明了我的问题和预期结果(即 expected_outcome
列)。
例如:
前 3 行在
trial
列中具有值T1
,在group
列中具有值D1, D2, D3
。接下来的 3 行在
trial
列中具有值T3
,在group
.[=24= 列中具有值D3, D2, D1
]
因为集合 D1, D2, D3
与 D3, 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")
)
您可以通过 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))
我认为您专栏中的最后一个 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))
注意:此答案基于编辑 OP 之前的 original problem,其中组必须由他们自己识别,没有错误的 'trial'
列.
factor
化组列,并使用 ave
计算每个组中 duplicated
的 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")