英文:
How to create a column with percentages for specific values for a group in R
问题
我有这个数据集
dat = structure(list(mdm = 7:8, price = c(100L, 200L), count = c(200L, 300L)),
class = "data.frame", row.names = c(NA, -2L))
我需要通过添加一个百分比列来转换这个数据,每个mdm
组都应该有一个perc
列,其值为
50, 60, 70, 80, 85, 90, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 110, 115, 120, 130, 140, 150
在值 100
对面,应该有来自dat
数据集的每个mdm
组的price
和count
值。
期望的输出:
perc price count
50 NA NA
60 NA NA
70 NA NA
80 NA NA
85 NA NA
90 NA NA
95 NA NA
96 NA NA
97 NA NA
98 NA NA
99 NA NA
**100 100 200**
101 NA NA
102 NA NA
103 NA NA
104 NA NA
105 NA NA
110 NA NA
115 NA NA
120 NA NA
130 NA NA
140 NA NA
150 NA NA
50 NA NA
60 NA NA
70 NA NA
80 NA NA
85 NA NA
90 NA NA
95 NA NA
96 NA NA
97 NA NA
98 NA NA
99 NA NA
**100 200 300**
101 NA NA
102 NA NA
103 NA NA
104 NA NA
105 NA NA
110 NA NA
115 NA NA
120 NA NA
130 NA NA
140 NA NA
150 NA NA
mdm=7
的价格和数量的值等于 100 和 200,所以我们将它们放在值 100
附近。
mdm=8
的价格和数量的值等于 200 和 300,所以我们将它们放在值 100
附近。
如何简单实现这个转换?谢谢您的帮助。
英文:
I have this dataset
dat = structure(list(mdm = 7:8, price = c(100L, 200L), count = c(200L, 300L)),
class = "data.frame", row.names = c(NA, -2L))
I need to transform this data by adding a column with percentages for each mdm
group. Each group should have a perc
column with values
50, 60, 70, 80, 85, 90, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 110, 115, 120, 130, 140, 150
where opposite the value 100
, there should be a price
and count
value for each group of mdm
from the dat
dataset.
Desired output:
perc price count
50 NA NA
60 NA NA
70 NA NA
80 NA NA
85 NA NA
90 NA NA
95 NA NA
96 NA NA
97 NA NA
98 NA NA
99 NA NA
**100 100 200**
101 NA NA
102 NA NA
103 NA NA
104 NA NA
105 NA NA
110 NA NA
115 NA NA
120 NA NA
130 NA NA
140 NA NA
150 NA NA
50 NA NA
60 NA NA
70 NA NA
80 NA NA
85 NA NA
90 NA NA
95 NA NA
96 NA NA
97 NA NA
98 NA NA
99 NA NA
**100 200 300**
101 NA NA
102 NA NA
103 NA NA
104 NA NA
105 NA NA
110 NA NA
115 NA NA
120 NA NA
130 NA NA
140 NA NA
150 NA NA
mdm=7
values for price and count are equal to 100 and 200, so we put them down near the point where 100
.
mdm=8
values for price and count are equal to 200 and 300, so we put them down near the point where 100
.
What is the easy way to do it? Thank you for your help.
答案1
得分: 1
将其与expand.grid
合并。
merge(cbind(dat, perc=100),
expand.grid(mdm=unique(dat$mdm), perc=c(50, 60, 70, 80, 85, 90, 95, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105,
110, 115, 120, 130, 140, 150)),
all=TRUE)
# mdm perc price count
# 1 7 50 NA NA
# 2 7 60 NA NA
# 3 7 70 NA NA
# 4 7 80 NA NA
# 5 7 85 NA NA
# 6 7 90 NA NA
# 7 7 95 NA NA
# 8 7 96 NA NA
# 9 7 97 NA NA
# 10 7 98 NA NA
# 11 7 99 NA NA
# 12 7 100 100 200
# 13 7 101 NA NA
# 14 7 102 NA NA
# 15 7 103 NA NA
# 16 7 104 NA NA
# 17 7 105 NA NA
# 18 7 110 NA NA
# 19 7 115 NA NA
# 20 7 120 NA NA
# 21 7 130 NA NA
# 22 7 140 NA NA
# 23 7 150 NA NA
# 24 8 50 NA NA
# 25 8 60 NA NA
# 26 8 70 NA NA
# 27 8 80 NA NA
# 28 8 85 NA NA
# 29 8 90 NA NA
# 30 8 95 NA NA
# 31 8 96 NA NA
# 32 8 97 NA NA
# 33 8 98 NA NA
# 34 8 99 NA NA
# 35 8 100 200 300
# 36 8 101 NA NA
# 37 8 102 NA NA
# 38 8 103 NA NA
# 39 8 104 NA NA
# 40 8 105 NA NA
# 41 8 110 NA NA
# 42 8 115 NA NA
# 43 8 120 NA NA
# 44 8 130 NA NA
# 45 8 140 NA NA
# 46 8 150 NA NA
英文:
merge
it with an expand.grid
.
merge(cbind(dat, perc=100),
expand.grid(mdm=unique(dat$mdm), perc=c(50, 60, 70, 80, 85, 90, 95, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105,
110, 115, 120, 130, 140, 150)),
all=TRUE)
# mdm perc price count
# 1 7 50 NA NA
# 2 7 60 NA NA
# 3 7 70 NA NA
# 4 7 80 NA NA
# 5 7 85 NA NA
# 6 7 90 NA NA
# 7 7 95 NA NA
# 8 7 96 NA NA
# 9 7 97 NA NA
# 10 7 98 NA NA
# 11 7 99 NA NA
# 12 7 100 100 200
# 13 7 101 NA NA
# 14 7 102 NA NA
# 15 7 103 NA NA
# 16 7 104 NA NA
# 17 7 105 NA NA
# 18 7 110 NA NA
# 19 7 115 NA NA
# 20 7 120 NA NA
# 21 7 130 NA NA
# 22 7 140 NA NA
# 23 7 150 NA NA
# 24 8 50 NA NA
# 25 8 60 NA NA
# 26 8 70 NA NA
# 27 8 80 NA NA
# 28 8 85 NA NA
# 29 8 90 NA NA
# 30 8 95 NA NA
# 31 8 96 NA NA
# 32 8 97 NA NA
# 33 8 98 NA NA
# 34 8 99 NA NA
# 35 8 100 200 300
# 36 8 101 NA NA
# 37 8 102 NA NA
# 38 8 103 NA NA
# 39 8 104 NA NA
# 40 8 105 NA NA
# 41 8 110 NA NA
# 42 8 115 NA NA
# 43 8 120 NA NA
# 44 8 130 NA NA
# 45 8 140 NA NA
# 46 8 150 NA NA
答案2
得分: 1
这是tidyverse方法的代码部分翻译:
library(dplyr)
library(tidyr)
vector <- paste(c(50, 60, 70, 80, 85, 90, 95:105, 110, 115, 120, 130, 140, 150), collapse = ", ")
dat %>%
group_by(mdm) %>%
mutate(perc = vector) %>%
separate_rows(perc, sep=",", convert = TRUE) %>%
ungroup() %>%
select(perc, price, count) %>%
mutate(across(-perc, ~ifelse(perc==100, ., NA_real_))) %>%
print(n=50)
perc price count
<int> <dbl> <dbl>
1 50 NA NA
2 60 NA NA
3 70 NA NA
4 80 NA NA
5 85 NA NA
6 90 NA NA
7 95 NA NA
8 96 NA NA
9 97 NA NA
10 98 NA NA
11 99 NA NA
12 100 100 200
13 101 NA NA
14 102 NA NA
15 103 NA NA
16 104 NA NA
17 105 NA NA
18 110 NA NA
19 115 NA NA
20 120 NA NA
21 130 NA NA
22 140 NA NA
23 150 NA NA
24 50 NA NA
25 60 NA NA
26 70 NA NA
27 80 NA NA
28 85 NA NA
29 90 NA NA
30 95 NA NA
31 96 NA NA
32 97 NA NA
33 98 NA NA
34 99 NA NA
35 100 200 300
36 101 NA NA
37 102 NA NA
38 103 NA NA
39 104 NA NA
40 105 NA NA
41 110 NA NA
42 115 NA NA
43 120 NA NA
44 130 NA NA
45 140 NA NA
46 150 NA NA
英文:
Here is tidyverse approach:
library(dplyr)
library(tidyr)
vector <- paste(c(50, 60, 70, 80, 85, 90, 95:105, 110, 115, 120, 130, 140, 150), collapse = ", ")
dat %>%
group_by(mdm) %>%
mutate(perc = vector) %>%
separate_rows(perc, sep=",", convert = TRUE) %>%
ungroup() %>%
select(perc, price, count) %>%
mutate(across(-perc, ~ifelse(perc==100, ., NA_real_))) %>%
print(n=50)
perc price count
<int> <dbl> <dbl>
1 50 NA NA
2 60 NA NA
3 70 NA NA
4 80 NA NA
5 85 NA NA
6 90 NA NA
7 95 NA NA
8 96 NA NA
9 97 NA NA
10 98 NA NA
11 99 NA NA
12 100 100 200
13 101 NA NA
14 102 NA NA
15 103 NA NA
16 104 NA NA
17 105 NA NA
18 110 NA NA
19 115 NA NA
20 120 NA NA
21 130 NA NA
22 140 NA NA
23 150 NA NA
24 50 NA NA
25 60 NA NA
26 70 NA NA
27 80 NA NA
28 85 NA NA
29 90 NA NA
30 95 NA NA
31 96 NA NA
32 97 NA NA
33 98 NA NA
34 99 NA NA
35 100 200 300
36 101 NA NA
37 102 NA NA
38 103 NA NA
39 104 NA NA
40 105 NA NA
41 110 NA NA
42 115 NA NA
43 120 NA NA
44 130 NA NA
45 140 NA NA
46 150 NA NA
答案3
得分: 1
你可以使用 tidyr
中的 complete
函数:
tidyr::complete(
cbind(dat, perc = 100),
mdm, perc = c(50, 60, 70, 80, 85, 90, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 110, 115, 120, 130, 140, 150)
)
输出:
# 一个 tibble: 46 × 4
mdm perc price count
<int> <dbl> <int> <int>
1 7 50 NA NA
2 7 60 NA NA
3 7 70 NA NA
4 7 80 NA NA
5 7 85 NA NA
6 7 90 NA NA
7 7 95 NA NA
8 7 96 NA NA
9 7 97 NA NA
10 7 98 NA NA
11 7 99 NA NA
12 7 100 100 200
13 7 101 NA NA
14 7 102 NA NA
15 7 103 NA NA
16 7 104 NA NA
17 7 105 NA NA
18 7 110 NA NA
19 7 115 NA NA
20 7 120 NA NA
21 7 130 NA NA
22 7 140 NA NA
23 7 150 NA NA
24 8 50 NA NA
25 8 60 NA NA
26 8 70 NA NA
27 8 80 NA NA
28 8 85 NA NA
29 8 90 NA NA
30 8 95 NA NA
31 8 96 NA NA
32 8 97 NA NA
33 8 98 NA NA
34 8 99 NA NA
35 8 100 200 300
36 8 101 NA NA
37 8 102 NA NA
38 8 103 NA NA
39 8 104 NA NA
40 8 105 NA NA
41 8 110 NA NA
42 8 115 NA NA
43 8 120 NA NA
44 8 130 NA NA
45 8 140 NA NA
46 8 150 NA NA
这是 R 代码的翻译。
英文:
You can use complete
from tidyr
:
tidyr::complete(
cbind(dat, perc = 100),
mdm, perc = c(50, 60, 70, 80, 85, 90, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 110, 115, 120, 130, 140, 150)
)
Output:
# A tibble: 46 × 4
mdm perc price count
<int> <dbl> <int> <int>
1 7 50 NA NA
2 7 60 NA NA
3 7 70 NA NA
4 7 80 NA NA
5 7 85 NA NA
6 7 90 NA NA
7 7 95 NA NA
8 7 96 NA NA
9 7 97 NA NA
10 7 98 NA NA
11 7 99 NA NA
12 7 100 100 200
13 7 101 NA NA
14 7 102 NA NA
15 7 103 NA NA
16 7 104 NA NA
17 7 105 NA NA
18 7 110 NA NA
19 7 115 NA NA
20 7 120 NA NA
21 7 130 NA NA
22 7 140 NA NA
23 7 150 NA NA
24 8 50 NA NA
25 8 60 NA NA
26 8 70 NA NA
27 8 80 NA NA
28 8 85 NA NA
29 8 90 NA NA
30 8 95 NA NA
31 8 96 NA NA
32 8 97 NA NA
33 8 98 NA NA
34 8 99 NA NA
35 8 100 200 300
36 8 101 NA NA
37 8 102 NA NA
38 8 103 NA NA
39 8 104 NA NA
40 8 105 NA NA
41 8 110 NA NA
42 8 115 NA NA
43 8 120 NA NA
44 8 130 NA NA
45 8 140 NA NA
46 8 150 NA NA
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论