如何解决string 将值拆分为两列,然后将它们连接到一个新列中
我正在尝试为两列(str_split
和 Proteins
)调用 Positions.within.proteins
函数,然后在名为 ID
的新列中连接相应的值。
df <- data.frame(Proteins = c("Q99755;A2A3N6","O00329","O00444","O14965","O14976","Q6A1A2;O15530","O43318","O43526","O43930;P51817","O60331"),Positions.within.proteins = c("276;223","708","41","162","175","84;111","63","628","78;78","270"))
这是我的代码。
my.function <- function(x,y){
protein.names <- str_split(x,";")[[1]]
position.names <- str_split(y,";")[[1]]
ID <- list()
for (i in 1:length(protein.names)){
ID[i] <- paste(protein.names[i],position.names[i],sep ="_")
}
ID.2 <- unlist(ID)
return(ID.2)
}
当我在单行上调用该函数时,它在某种程度上起作用。
row1 <- my.function(df$Proteins[1],df$Positions.within.proteins[1])
"Q99755_276" "A2A3N6_223"
但我的问题是:
- 如何将此函数应用于整个数据框?
- 如何将
"Q99755_276" "A2A3N6_223"
转换成我想要的"Q99755_276;A2A3N6_223"
我想使用 apply
函数,但不确定 apply
函数是否可以接受两个参数。
这里展示了它应该是什么样子。
df.final <- data.frame(Proteins = c("Q99755;A2A3N6","270"),ID = c("Q99755_276;A2A3N6_223","O00329_708","O00444_41","O14965_162","O14976_175","Q6A1A2_84;O15530_111","O43318_63","O43526_628","O43930_78;P51817_78","O60331_270"
))
有谁知道如何实现这些?非常感谢您的帮助!
解决方法
您要找的是tidyr::unite()
:
tidyr::unite(data = iris,col = "new_column",Species,Sepal.Length,sep = ";")
试试看。它需要一个数据框(在本例中为 iris)、您的新列的名称 (new_column)、您想要连接在一起的列(Species 和 Sepal.Length),以及您想要将它们分开的值(a分号)。 tidyr::separate()
与 unite()
正好相反——它根据原始中的分隔符创建两个新列。
编辑
好吧,你需要更有创意...尝试用 tidyr::separate()
将每个蛋白质分成自己的列,对蛋白质位置执行相同操作,然后将每个蛋白质与其位置结合起来。然后,用分号作为分隔符将两种蛋白质结合在一起。最后,删除仅使用一种蛋白质的情况下的缺失值(它们将始终具有相同的形式,最后以 ;NA_NA
格式)。中提琴:
library(tidyr)
library(dplyr)
library(stringr)
df %>%
separate(col = Proteins,c("protein1","protein2"),";",remove = FALSE) %>%
separate(col = Positions.within.proteins,into = c("position_p1","position_p2"),remove = FALSE) %>%
unite(col = "id_part1",sep = "_",protein1,position_p1) %>%
unite(col = "id_part2",protein2,position_p2) %>%
unite(col = "id",sep = ";",id_part1,id_part2) %>%
mutate(id = str_remove_all(id,";NA_NA"))
另一个编辑
我做了一些基准测试,我的实现也快了一点:
rbenchmark::benchmark(
mine = df %>%
separate(col = Proteins,remove = FALSE) %>%
separate(col = Positions.within.proteins,remove = FALSE) %>%
unite(col = "id_part1",position_p1) %>%
unite(col = "id_part2",position_p2) %>%
unite(col = "id",id_part2) %>%
mutate(id = str_remove_all(id,";NA_NA")),alt_implementation = df %>%
rowwise() %>%
mutate(ID = map2(Proteins,Positions.within.proteins,my.function)) %>%
unnest_wider(ID,names_sep = '.') %>%
unite(contains('ID'),col = 'ID',remove = TRUE,na.rm = TRUE),replications = 1000
)
# test replications elapsed relative user.self sys.self user.child sys.child
# 1 mine 1000 9.06 1.000 8.97 0.05 NA NA
# 2 alt_implementation 1000 11.77 1.299 11.73 0.00 NA NA
,
您可以使用您的功能和tidyverse
使用 mutate()
和 map2(.f = my.function)
创建嵌套 ID 列,该列包含一个列表列,每行包含所有 ID(在示例数据中有些有 1 个 ID,有些有两个)。然后您可以 unnest_wider()
创建几个不同的 ID 列,您可以使用 tidyr::unite()
library(tidyr)
library(dplyr)
library(stringr)
library(purrr)
df %>% mutate(ID=map2(Proteins,my.function))%>%
unnest_wider(ID,names_sep = '.')%>%
unite(contains('ID'),col='ID',sep=";",na.rm=TRUE)
# A tibble: 10 x 3
Proteins Positions.within.proteins ID
<chr> <chr> <chr>
1 Q99755;A2A3N6 276;223 Q99755_276;A2A3N6_223
2 O00329 708 O00329_708
3 O00444 41 O00444_41
4 O14965 162 O14965_162
5 O14976 175 O14976_175
6 Q6A1A2;O15530 84;111 Q6A1A2_84;O15530_111
7 O43318 63 O43318_63
8 O43526 628 O43526_628
9 O43930;P51817 78;78 O43930_78;P51817_78
10 O60331 270 O60331_270
,
一个简短的基本 R 解决方案。
df$ID <- apply(df,1,\(x) paste(do.call(\(y,z) paste0(y,"_",z),unname(strsplit(x,';'))),collapse=';'))
df
# Proteins Positions.within.proteins ID
# 1 Q99755;A2A3N6 276;223 Q99755_276;A2A3N6_223
# 2 O00329 708 O00329_708
# 3 O00444 41 O00444_41
# 4 O14965 162 O14965_162
# 5 O14976 175 O14976_175
# 6 Q6A1A2;O15530 84;111 Q6A1A2_84;O15530_111
# 7 O43318 63 O43318_63
# 8 O43526 628 O43526_628
# 9 O43930;P51817 78;78 O43930_78;P51817_78
# 10 O60331 270 O60331_270
,
这是使用 strsplit
和 mapply
的基本 R 方法 -
df$ID <- mapply(function(x,y) paste(x,y,collapse = ';',sep = '_'),strsplit(df$Proteins,';'),strsplit(df$Positions.within.proteins,';'))
df
# Proteins Positions.within.proteins ID
#1 Q99755;A2A3N6 276;223 Q99755_276;A2A3N6_223
#2 O00329 708 O00329_708
#3 O00444 41 O00444_41
#4 O14965 162 O14965_162
#5 O14976 175 O14976_175
#6 Q6A1A2;O15530 84;111 Q6A1A2_84;O15530_111
#7 O43318 63 O43318_63
#8 O43526 628 O43526_628
#9 O43930;P51817 78;78 O43930_78;P51817_78
#10 O60331 270 O60331_270
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。