如何仅使用目标列的一个值来使用 Spread 函数?
How to use the Spread function using only one value of the target column?
我们有以下数据框 a
,内容如下:
> a
google_prod Value
1 categoria ML
2 google 120
3 youtube 24
4 categoria AO
5 google 2
6 youtube 0
7 categoria ML
8 google 27
9 youtube 0
10 categoria AO
11 google 5
12 youtube 0
我们想得到这个:
categoria google_prod Value
1 ML google 120
2 ML youtube 24
3 AO google 2
4 AO youtube 0
5 ML google 27
6 ML youtube 0
7 AO google 5
8 AO youtube 0
换句话说,执行 Spread 或类似函数的一种应用,其中仅从 google_prod 列中获取一个值来应用它,在这种情况下它将是 'categoria'值。
library(tidyverse)
# getting the data
category <- rep(c("categoria", "google", "youtube"), 4)
value <- c("ML", "120", "24", "AO", "2", "0", "ML", "27", "0", "AO", "5", "0")
df <- tibble(category, value)
df %>%
mutate(helper = rep(1:(nrow(df)/3), each = 3)) %>%
pivot_wider(names_from = category, values_from = value) %>%
select(-helper) %>%
pivot_longer(names_to = "google_prod", values_to = "values", -1)
# # A tibble: 8 x 3
# categoria google_prod values
# <chr> <chr> <chr>
# 1 ML google 120
# 2 ML youtube 24
# 3 AO google 2
# 4 AO youtube 0
# 5 ML google 27
# 6 ML youtube 0
# 7 AO google 5
# 8 AO youtube 0
一个想法如下。据我所见,您的目标值是 Value
中包含两个大写字母的值。我搜索了他们在哪里使用 grep()
并获得了索引。使用此信息,我使用 findIntervals()
创建了一个组变量。对于每个组,我汇总了数据;我提取大写字母值并将其放入 categoria
。以类似的方式,我又创建了两列。它们是列表。所以我最后用了unnest()
来得到输出。
library(tidyverse)
ind <- grep(x = mydf$Value, pattern = "[A-Z]+")
group_by(mydf, group = findInterval(x = 1:n(), vec = ind)) %>%
summarize(categoria = Value[google_prod == "categoria"],
Google_prod = list(google_prod[google_prod != "categoria"]),
Value = list(Value[google_prod != "categoria"])) %>%
unnest(cols = Google_prod:Value)
group categoria Google_prod Value
<int> <chr> <chr> <chr>
1 1 ML google 120
2 1 ML youtube 24
3 2 AO google 2
4 2 AO youtube 0
5 3 ML google 27
6 3 ML youtube 0
7 4 AO google 5
8 4 AO youtube 0
数据
mydf <- structure(list(google_prod = c("categoria", "google", "youtube",
"categoria", "google", "youtube", "categoria", "google", "youtube",
"categoria", "google", "youtube"), Value = c("ML", "120", "24",
"AO", "2", "0", "ML", "27", "0", "AO", "5", "0")), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))
这是另一个想法,使用 cumsum
创建一个组并提取 first
元素
library(dplyr)
mydf %>%
group_by(grp = cumsum(google_prod == 'categoria')) %>%
mutate(categoria = first(Value)) %>%
slice(-1) %>%
ungroup %>%
select(-grp) %>%
type.convert(as.is = TRUE)
# A tibble: 8 x 3
# google_prod Value categoria
# <chr> <int> <chr>
#1 google 120 ML
#2 youtube 24 ML
#3 google 2 AO
#4 youtube 0 AO
#5 google 27 ML
#6 youtube 0 ML
#7 google 5 AO
#8 youtube 0 AO
数据
mydf <- structure(list(google_prod = c("categoria", "google", "youtube",
"categoria", "google", "youtube", "categoria", "google", "youtube",
"categoria", "google", "youtube"), Value = c("ML", "120", "24",
"AO", "2", "0", "ML", "27", "0", "AO", "5", "0")),
class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))
我们有以下数据框 a
,内容如下:
> a
google_prod Value
1 categoria ML
2 google 120
3 youtube 24
4 categoria AO
5 google 2
6 youtube 0
7 categoria ML
8 google 27
9 youtube 0
10 categoria AO
11 google 5
12 youtube 0
我们想得到这个:
categoria google_prod Value
1 ML google 120
2 ML youtube 24
3 AO google 2
4 AO youtube 0
5 ML google 27
6 ML youtube 0
7 AO google 5
8 AO youtube 0
换句话说,执行 Spread 或类似函数的一种应用,其中仅从 google_prod 列中获取一个值来应用它,在这种情况下它将是 'categoria'值。
library(tidyverse)
# getting the data
category <- rep(c("categoria", "google", "youtube"), 4)
value <- c("ML", "120", "24", "AO", "2", "0", "ML", "27", "0", "AO", "5", "0")
df <- tibble(category, value)
df %>%
mutate(helper = rep(1:(nrow(df)/3), each = 3)) %>%
pivot_wider(names_from = category, values_from = value) %>%
select(-helper) %>%
pivot_longer(names_to = "google_prod", values_to = "values", -1)
# # A tibble: 8 x 3
# categoria google_prod values
# <chr> <chr> <chr>
# 1 ML google 120
# 2 ML youtube 24
# 3 AO google 2
# 4 AO youtube 0
# 5 ML google 27
# 6 ML youtube 0
# 7 AO google 5
# 8 AO youtube 0
一个想法如下。据我所见,您的目标值是 Value
中包含两个大写字母的值。我搜索了他们在哪里使用 grep()
并获得了索引。使用此信息,我使用 findIntervals()
创建了一个组变量。对于每个组,我汇总了数据;我提取大写字母值并将其放入 categoria
。以类似的方式,我又创建了两列。它们是列表。所以我最后用了unnest()
来得到输出。
library(tidyverse)
ind <- grep(x = mydf$Value, pattern = "[A-Z]+")
group_by(mydf, group = findInterval(x = 1:n(), vec = ind)) %>%
summarize(categoria = Value[google_prod == "categoria"],
Google_prod = list(google_prod[google_prod != "categoria"]),
Value = list(Value[google_prod != "categoria"])) %>%
unnest(cols = Google_prod:Value)
group categoria Google_prod Value
<int> <chr> <chr> <chr>
1 1 ML google 120
2 1 ML youtube 24
3 2 AO google 2
4 2 AO youtube 0
5 3 ML google 27
6 3 ML youtube 0
7 4 AO google 5
8 4 AO youtube 0
数据
mydf <- structure(list(google_prod = c("categoria", "google", "youtube",
"categoria", "google", "youtube", "categoria", "google", "youtube",
"categoria", "google", "youtube"), Value = c("ML", "120", "24",
"AO", "2", "0", "ML", "27", "0", "AO", "5", "0")), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))
这是另一个想法,使用 cumsum
创建一个组并提取 first
元素
library(dplyr)
mydf %>%
group_by(grp = cumsum(google_prod == 'categoria')) %>%
mutate(categoria = first(Value)) %>%
slice(-1) %>%
ungroup %>%
select(-grp) %>%
type.convert(as.is = TRUE)
# A tibble: 8 x 3
# google_prod Value categoria
# <chr> <int> <chr>
#1 google 120 ML
#2 youtube 24 ML
#3 google 2 AO
#4 youtube 0 AO
#5 google 27 ML
#6 youtube 0 ML
#7 google 5 AO
#8 youtube 0 AO
数据
mydf <- structure(list(google_prod = c("categoria", "google", "youtube",
"categoria", "google", "youtube", "categoria", "google", "youtube",
"categoria", "google", "youtube"), Value = c("ML", "120", "24",
"AO", "2", "0", "ML", "27", "0", "AO", "5", "0")),
class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))