R语言:如何合并两列生成按字母排序的新列FruitsDiff?
问题描述
现有如下数据集:
ID<-c("A","B","C","D","E") Fruits1<-c("orange","apple","pineapple","apple","pineapple") Fruits2<-c("apple","orange","apple","pineapple","orange") data<-tibble(ID,Fruits1,Fruits2) data # A tibble: 5 × 3 ID Fruits1 Fruits2 <chr> <chr> <chr> 1 A orange apple 2 B apple orange 3 C pineapple apple 4 D apple pineapple 5 E pineapple orange
需要新增一列FruitsDiff,将Fruits1和Fruits2的内容按字母顺序排序后合并——无论原列中水果的先后顺序如何,合并结果都保持一致(比如第1行原顺序是orange在前、apple在后,合并后为apple-orange),分隔符可自定义。
解决方案
方法1:dplyr + purrr 行级处理
用rowwise()对每行单独操作,结合sort()排序后拼接:
library(dplyr) library(purrr) data <- data %>% rowwise() %>% mutate(FruitsDiff = paste(sort(c(Fruits1, Fruits2)), collapse = "-")) %>% ungroup()
如果数据存在大小写差异(比如Pineapple和pineapple),可以先统一转小写再排序:
data <- data %>% rowwise() %>% mutate(FruitsDiff = paste(sort(tolower(c(Fruits1, Fruits2))), collapse = "-")) %>% ungroup()
方法2:Base R 原生实现
无需额外加载包,用apply()逐行处理:
data$FruitsDiff <- apply(data[, c("Fruits1", "Fruits2")], 1, function(x) { paste(sort(x), collapse = "-") })
处理大小写的版本:
data$FruitsDiff <- apply(data[, c("Fruits1", "Fruits2")], 1, function(x) { paste(sort(tolower(x)), collapse = "-") })
方法3:tidyr 宽转长扩展方案(适配多列场景)
如果后续需要处理更多水果列,这种方法更灵活:
library(tidyr) library(dplyr) data <- data %>% pivot_longer(cols = starts_with("Fruits"), names_to = NULL, values_to = "fruit") %>% mutate(fruit = tolower(fruit)) %>% group_by(ID) %>% arrange(fruit, .by_group = TRUE) %>% summarise(FruitsDiff = paste(fruit, collapse = "-"), .groups = "drop") %>% left_join(data, by = "ID") %>% select(ID, Fruits1, Fruits2, FruitsDiff)
运行后可得到目标结果:
# A tibble: 5 × 4 ID Fruits1 Fruits2 FruitsDiff <chr> <chr> <chr> <chr> 1 A orange apple apple-orange 2 B apple orange apple-orange 3 C pineapple apple apple-pineapple 4 D apple pineapple apple-pineapple 5 E pineapple orange orange-pineapple
内容的提问来源于stack exchange,提问作者Cam
相关产品推荐
相关产品推荐

