R语言 右|如何按自定义顺序排列df列的字符向量?

67up9zun  于 2023-02-20  发布在  其他
关注(0)|答案(2)|浏览(105)

我有一个 Dataframe ,看起来像这样:
| 水果|十|是|Z型|
| - ------|- ------|- ------|- ------|
| 苹果、香蕉、橙子、木瓜|项目a|f级|k|
| 香蕉、橘子、葡萄|b.人口基金|克|升|
| 橙子香蕉|(c)秘书长的报告|小时|米|
| 葡萄|日|我|数量|
| 香蕉、葡萄、橙子、苹果、木瓜|电子|j|阿|
我想在每一行中设置一个自定义的显示顺序。例如:
1.苹果
1.橙色
1.木瓜
1.香蕉
1.葡萄
因此,该列将如下所示:
| 水果|十|是|Z型|
| - ------|- ------|- ------|- ------|
| 苹果、橙子、木瓜、香蕉|项目a|f级|k|
| 橙子香蕉葡萄|b.人口基金|克|升|
| 橙子香蕉|(c)秘书长的报告|小时|米|
| 葡萄|日|我|数量|
| 苹果、橙子、木瓜、香蕉、葡萄|电子|j|阿|
我该怎么做???我试过其他帖子的建议,但它们都是关于排列 Dataframe 行的,这不是我需要的...
附言:有没有办法在管道里做这个?

c9qzyr3d

c9qzyr3d1#

我们可以

library(dplyr)
library(stringr)
library(purrr)
df1 <- df1 %>%
   mutate(Fruit = map_chr(strsplit(Fruit, ",\\s*"), 
        ~ toString(.x[order(match(.x,
  c("apple", "orange", "papaya", "banana", "grape")))])))
  • 输出
df1
                                  Fruit X Y Z
1        apple, orange, papaya, banana a f k
2                orange, banana, grape b g l
3                       orange, banana c h m
4                                grape d i n
5 apple, orange, papaya, banana, grape e j o

或者使用separate_longer_delim

library(tidyr)
df1 <- df1 %>%
  mutate(rn = row_number()) %>%
  separate_longer_delim(Fruit, delim = regex(",\\s*")) %>% 
  arrange(rn, factor(Fruit, 
   levels = c("apple", "orange", "papaya", "banana", "grape"))) %>% 
  reframe(Fruit = str_c(Fruit, collapse = ", "),
    .by = c("rn", "X", "Y", "Z")) %>% 
  select(-rn) %>%
  relocate(Fruit, .before = 1)
  • 输出
df1
                                 Fruit X Y Z
1        apple, orange, papaya, banana a f k
2                orange, banana, grape b g l
3                       orange, banana c h m
4                                grape d i n
5 apple, orange, papaya, banana, grape e j o

如果列是list,则不需要strsplit

df1 <- df1 %>%
   mutate(Fruit = map(Fruit, 
  ~ .x[order(match(.x, c("apple", "orange", "papaya", "banana", "grape")))]))

或使用unnest

df1 <- df1 %>% 
  mutate(rn = row_number()) %>% 
  unnest(Fruit) %>% 
  arrange(rn, factor(Fruit, 
   levels = c("apple", "orange", "papaya", "banana", "grape"))) %>% 
  reframe(Fruit = list(Fruit),
    .by = c("rn", "X", "Y", "Z")) %>% 
  select(-rn) %>%
  relocate(Fruit, .before = 1)
  • 输出
df1
# A tibble: 5 × 4
  Fruit     X     Y     Z    
  <list>    <chr> <chr> <chr>
1 <chr [4]> a     f     k    
2 <chr [3]> b     g     l    
3 <chr [2]> c     h     m    
4 <chr [1]> d     i     n    
5 <chr [5]> e     j     o

数据

df1 <- structure(list(Fruit = c("apple, banana, orange, papaya", "banana, orange, grape", 
"orange, banana", "grape", "banana, grape, orange, apple, papaya"
), X = c("a", "b", "c", "d", "e"), Y = c("f", "g", "h", "i", 
"j"), Z = c("k", "l", "m", "n", "o")), class = "data.frame", row.names = c(NA, 
-5L))
3npbholx

3npbholx2#

下面是另一个(tidyverse解决方案):
主要功能是使用separate_rows,然后创建factor类,级别如下:

library(dplyr)
library(tidyr)

df %>% 
  group_by(group = row_number()) %>% 
  separate_rows(Fruit) %>% 
  mutate(Fruit= factor(Fruit, levels = c("apple", "orange", "papaya", "banana", "grape"))) %>% 
  arrange(Fruit, .by_group = TRUE) %>% 
  summarise(Fruit = toString(Fruit)) %>% 
  bind_cols(df[2:4]) %>% 
  select(-group)
Fruit                                X     Y     Z    
  <chr>                                <chr> <chr> <chr>
1 apple, orange, papaya, banana        a     f     k    
2 orange, banana, grape                b     g     l    
3 orange, banana                       c     h     m    
4 grape                                d     i     n    
5 apple, orange, papaya, banana, grape e     j     o

相关问题