R 如何计算单元格中分号分隔的值?

R 如何计算单元格中分号分隔的值?,r,R,我有一张这样的桌子: > head(dt) variant_id transcript_id HH HNL NLNL 1: chr10_60842447_A_G_b38 chr10_60871326_60871443 32968;685 1440;20 337;1 2: chr10_60846892_G_A_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 3:

我有一张这样的桌子:

> head(dt)
               variant_id           transcript_id        HH     HNL  NLNL
1: chr10_60842447_A_G_b38 chr10_60871326_60871443 32968;685 1440;20 337;1
2: chr10_60846892_G_A_b38 chr10_60871326_60871443 33157;690 1251;15 337;1
3: chr10_60847284_C_T_b38 chr10_60871326_60871443 33157;690 1251;15 337;1
4: chr10_60849980_T_C_b38 chr10_60871326_60871443 33157;690 1251;15 337;1
5: chr10_60850566_A_T_b38 chr10_60871326_60871443 33157;690 1251;15 337;1
6: chr10_60852394_C_A_b38 chr10_60871326_60871443 33157;690 1251;15 337;1
我想做的是取列
HH
中的值,将分号前的数字除以分号后的数字。例如,对于第一行,我想执行
32968/685
(即
48.13
)。然后,我想对列
nl
中的值执行相同的操作(因此对于第一行
337
),然后我想从列
NLNL
中的值减去列
HH
中找到的值,因此
337-48.13=228.87
。然后,我想将该值放入一个新的列中,该列名为
diff
,用于所有行


我该怎么做呢?我可以很容易地找出如何将一列的值除以另一列,并将结果放入一个新列中,但我不知道如何从单元格中提取分号分隔的值并对其进行操作。

一个选项是
拆分
strsplit
,转换为
numeric
,并将第一个元素除以第二个元素

dt[, new := unlist(lapply(strsplit(HH, ";"), 
        function(x) as.numeric(x[1])/as.numeric(x[2])))]
或者另一个选项是将列作为
数据读取。使用
fread
读取表
,然后进行除法

dt[, new := fread(text = .SD[["HH"]], sep=";")[, V1/V2]]

对于多列,请在
.SDcols
中指定列,在列上循环并执行相同的操作

dt[, paste0("new", 1:3) := lapply(.SD, function(x) 
         fread(text = x, sep=";")[, V1/V2]), .SDcols = HH:NLNL]
dt
#               variant_id           transcript_id        HH     HNL  NLNL     new1 new2 new3
#1: chr10_60842447_A_G_b38 chr10_60871326_60871443 32968;685 1440;20 337;1 48.12847 72.0  337
#2: chr10_60846892_G_A_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 48.05362 83.4  337
#3: chr10_60847284_C_T_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 48.05362 83.4  337
#4: chr10_60849980_T_C_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 48.05362 83.4  337
#5: chr10_60850566_A_T_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 48.05362 83.4  337
#6: chr10_60852394_C_A_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 48.05362 83.4  337

或带有
tidyverse

library(dplyr)
library(tidyr)
dt %>%
    mutate(rn = row_number()) %>% 
    separate_rows(HH, HNL, NLNL, convert = TRUE) %>% 
    group_by(rn, variant_id, transcript_id) %>% 
    summarise_at(vars(HH:NLNL), ~ first(.)/last(.)) %>%
    ungroup %>% 
    select(-rn)
# A tibble: 6 x 5
#  variant_id             transcript_id              HH   HNL  NLNL
#  <chr>                  <chr>                   <dbl> <dbl> <dbl>
#1 chr10_60842447_A_G_b38 chr10_60871326_60871443  48.1  72     337
#2 chr10_60846892_G_A_b38 chr10_60871326_60871443  48.1  83.4   337
#3 chr10_60847284_C_T_b38 chr10_60871326_60871443  48.1  83.4   337
#4 chr10_60849980_T_C_b38 chr10_60871326_60871443  48.1  83.4   337
#5 chr10_60850566_A_T_b38 chr10_60871326_60871443  48.1  83.4   337
#6 chr10_60852394_C_A_b38 chr10_60871326_60871443  48.1  83.4   337
数据
dt一个选项是按
拆分
strsplit
,转换为
numeric
,并将第一个元素除以第二个元素

dt[, new := unlist(lapply(strsplit(HH, ";"), 
        function(x) as.numeric(x[1])/as.numeric(x[2])))]
或者另一个选项是将列作为
数据读取。使用
fread
读取表
,然后进行除法

dt[, new := fread(text = .SD[["HH"]], sep=";")[, V1/V2]]

对于多列,请在
.SDcols
中指定列,在列上循环并执行相同的操作

dt[, paste0("new", 1:3) := lapply(.SD, function(x) 
         fread(text = x, sep=";")[, V1/V2]), .SDcols = HH:NLNL]
dt
#               variant_id           transcript_id        HH     HNL  NLNL     new1 new2 new3
#1: chr10_60842447_A_G_b38 chr10_60871326_60871443 32968;685 1440;20 337;1 48.12847 72.0  337
#2: chr10_60846892_G_A_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 48.05362 83.4  337
#3: chr10_60847284_C_T_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 48.05362 83.4  337
#4: chr10_60849980_T_C_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 48.05362 83.4  337
#5: chr10_60850566_A_T_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 48.05362 83.4  337
#6: chr10_60852394_C_A_b38 chr10_60871326_60871443 33157;690 1251;15 337;1 48.05362 83.4  337

或带有
tidyverse

library(dplyr)
library(tidyr)
dt %>%
    mutate(rn = row_number()) %>% 
    separate_rows(HH, HNL, NLNL, convert = TRUE) %>% 
    group_by(rn, variant_id, transcript_id) %>% 
    summarise_at(vars(HH:NLNL), ~ first(.)/last(.)) %>%
    ungroup %>% 
    select(-rn)
# A tibble: 6 x 5
#  variant_id             transcript_id              HH   HNL  NLNL
#  <chr>                  <chr>                   <dbl> <dbl> <dbl>
#1 chr10_60842447_A_G_b38 chr10_60871326_60871443  48.1  72     337
#2 chr10_60846892_G_A_b38 chr10_60871326_60871443  48.1  83.4   337
#3 chr10_60847284_C_T_b38 chr10_60871326_60871443  48.1  83.4   337
#4 chr10_60849980_T_C_b38 chr10_60871326_60871443  48.1  83.4   337
#5 chr10_60850566_A_T_b38 chr10_60871326_60871443  48.1  83.4   337
#6 chr10_60852394_C_A_b38 chr10_60871326_60871443  48.1  83.4   337
数据
dt涉及
dplyr
gsubfn
的一个选项可以是:

df %>%
 mutate_at(vars(HH, HNL, NLNL), ~ gsubfn("([0-9]+);([0-9]+)", function(x, y) as.numeric(x)/as.numeric(y), .))

             variant_id           transcript_id               HH  HNL NLNL
1 chr10_60842447_A_G_b38 chr10_60871326_60871443 48.1284671532847   72  337
2 chr10_60846892_G_A_b38 chr10_60871326_60871443 48.0536231884058 83.4  337
3 chr10_60847284_C_T_b38 chr10_60871326_60871443 48.0536231884058 83.4  337
4 chr10_60849980_T_C_b38 chr10_60871326_60871443 48.0536231884058 83.4  337
5 chr10_60850566_A_T_b38 chr10_60871326_60871443 48.0536231884058 83.4  337
6 chr10_60852394_C_A_b38 chr10_60871326_60871443 48.0536231884058 83.4  33

涉及
dplyr
gsubfn
的一个选项可以是:

df %>%
 mutate_at(vars(HH, HNL, NLNL), ~ gsubfn("([0-9]+);([0-9]+)", function(x, y) as.numeric(x)/as.numeric(y), .))

             variant_id           transcript_id               HH  HNL NLNL
1 chr10_60842447_A_G_b38 chr10_60871326_60871443 48.1284671532847   72  337
2 chr10_60846892_G_A_b38 chr10_60871326_60871443 48.0536231884058 83.4  337
3 chr10_60847284_C_T_b38 chr10_60871326_60871443 48.0536231884058 83.4  337
4 chr10_60849980_T_C_b38 chr10_60871326_60871443 48.0536231884058 83.4  337
5 chr10_60850566_A_T_b38 chr10_60871326_60871443 48.0536231884058 83.4  337
6 chr10_60852394_C_A_b38 chr10_60871326_60871443 48.0536231884058 83.4  33

这是另一个选择。我们在一个嵌套的单元格中拆分数据,然后映射出值

library(tidyverse)

dt %>%
  mutate_at(vars(HH:NLNL), list(~str_split(., ";") )) %>%
  mutate_at(vars(HH:NLNL), list(~map_dbl(., ~as.numeric(.x) %>% {.[[1]]/.[[2]]}))) 

#>   variant_id             transcript_id              HH   HNL  NLNL
#>   <chr>                  <chr>                   <dbl> <dbl> <dbl>
#> 1 chr10_60842447_A_G_b38 chr10_60871326_60871443  48.1  72     337
#> 2 chr10_60846892_G_A_b38 chr10_60871326_60871443  48.1  83.4   337
#> 3 chr10_60847284_C_T_b38 chr10_60871326_60871443  48.1  83.4   337
#> 4 chr10_60849980_T_C_b38 chr10_60871326_60871443  48.1  83.4   337
#> 5 chr10_60850566_A_T_b38 chr10_60871326_60871443  48.1  83.4   337
#> 6 chr10_60852394_C_A_b38 chr10_60871326_60871443  48.1  83.4   337
库(tidyverse)
dt%>%
在(vars(HH:NLNL),list(~str_split(,“;”))))%%>%
mutate_at(vars(HH:nlnlnl),list(~map_dbl(,~as.numeric(.x)%>%{[1]/[2]})))
#>变体id转录本id HH HNL NL
#>                                          
#>1 chr10_60842447_A_G_b38 chr10_60871326_60871443 48.1 72 337
#>2 chr10_60846892_G_A_b38 chr10_60871326_60871443 48.1 83.4 337
#>3 chr10_60847284_C_T_b38 chr10_60871326_60871443 48.1 83.4 337
#>4 chr10_60849980_T_C_b38 chr10_60871326_60871443 48.1 83.4 337
#>5 chr10_6085066_A_T_b38 chr10_60871326_60871443 48.1 83.4 337
#>6 chr10_60852394_C_A_b38 chr10_60871326_60871443 48.1 83.4 337
编辑:要获得新变量,只需在列表中命名它们:

dt %>%
  mutate_at(vars(HH:NLNL), list(new = ~str_split(., ";") )) %>%
  mutate_at(vars(HH_new:NLNL_new), list(~map_dbl(., ~as.numeric(.x) %>% {.[[1]]/.[[2]]})))

#>   variant_id       transcript_id      HH     HNL   NLNL  HH_new HNL_new NLNL_new
#>   <chr>            <chr>              <chr>  <chr> <chr>  <dbl>   <dbl>    <dbl>
#> 1 chr10_60842447_… chr10_60871326_60… 32968… 1440… 337;1   48.1    72        337
#> 2 chr10_60846892_… chr10_60871326_60… 33157… 1251… 337;1   48.1    83.4      337
#> 3 chr10_60847284_… chr10_60871326_60… 33157… 1251… 337;1   48.1    83.4      337
#> 4 chr10_60849980_… chr10_60871326_60… 33157… 1251… 337;1   48.1    83.4      337
#> 5 chr10_60850566_… chr10_60871326_60… 33157… 1251… 337;1   48.1    83.4      337
#> 6 chr10_60852394_… chr10_60871326_60… 33157… 1251… 337;1   48.1    83.4      337
dt%>%
在(vars(HH:NLNL),list(new=~str_split(,“;”)))%%>%
mutate_at(vars(HH_new:NLNL_new),list(~map_dbl(,~as.numeric(.x)%>%{[1]/[2]})))
#>变体id转录本id HH HNL NL HH新HNL新NL新
#>                                         
#>1 chr10_6084247_…chr10_60871326_60…32968…1440…337;1   48.1    72        337
#>2 chr10_60846892_…chr10_60871326_60…33157…1251…337;1   48.1    83.4      337
#>3 chr10_60847284_…chr10_60871326_60…33157…1251…337;1   48.1    83.4      337
#>4 chr10_60849980_…chr10_60871326_60…33157…1251…337;1   48.1    83.4      337
#>5 chr10_6085066_u10_60871326_60…33157…1251…337;1   48.1    83.4      337
#>6 chr10_60852394_…chr10_60871326_60…33157…1251…337;1   48.1    83.4      337

这里是另一个选项。我们在一个嵌套的单元格中拆分数据,然后映射出值

library(tidyverse)

dt %>%
  mutate_at(vars(HH:NLNL), list(~str_split(., ";") )) %>%
  mutate_at(vars(HH:NLNL), list(~map_dbl(., ~as.numeric(.x) %>% {.[[1]]/.[[2]]}))) 

#>   variant_id             transcript_id              HH   HNL  NLNL
#>   <chr>                  <chr>                   <dbl> <dbl> <dbl>
#> 1 chr10_60842447_A_G_b38 chr10_60871326_60871443  48.1  72     337
#> 2 chr10_60846892_G_A_b38 chr10_60871326_60871443  48.1  83.4   337
#> 3 chr10_60847284_C_T_b38 chr10_60871326_60871443  48.1  83.4   337
#> 4 chr10_60849980_T_C_b38 chr10_60871326_60871443  48.1  83.4   337
#> 5 chr10_60850566_A_T_b38 chr10_60871326_60871443  48.1  83.4   337
#> 6 chr10_60852394_C_A_b38 chr10_60871326_60871443  48.1  83.4   337
库(tidyverse)
dt%>%
在(vars(HH:NLNL),list(~str_split(,“;”))))%%>%
mutate_at(vars(HH:nlnlnl),list(~map_dbl(,~as.numeric(.x)%>%{[1]/[2]})))
#>变体id转录本id HH HNL NL
#>                                          
#>1 chr10_60842447_A_G_b38 chr10_60871326_60871443 48.1 72 337
#>2 chr10_60846892_G_A_b38 chr10_60871326_60871443 48.1 83.4 337
#>3 chr10_60847284_C_T_b38 chr10_60871326_60871443 48.1 83.4 337
#>4 chr10_60849980_T_C_b38 chr10_60871326_60871443 48.1 83.4 337
#>5 chr10_6085066_A_T_b38 chr10_60871326_60871443 48.1 83.4 337
#>6 chr10_60852394_C_A_b38 chr10_60871326_60871443 48.1 83.4 337
编辑:要获得新变量,只需在列表中命名它们:

dt %>%
  mutate_at(vars(HH:NLNL), list(new = ~str_split(., ";") )) %>%
  mutate_at(vars(HH_new:NLNL_new), list(~map_dbl(., ~as.numeric(.x) %>% {.[[1]]/.[[2]]})))

#>   variant_id       transcript_id      HH     HNL   NLNL  HH_new HNL_new NLNL_new
#>   <chr>            <chr>              <chr>  <chr> <chr>  <dbl>   <dbl>    <dbl>
#> 1 chr10_60842447_… chr10_60871326_60… 32968… 1440… 337;1   48.1    72        337
#> 2 chr10_60846892_… chr10_60871326_60… 33157… 1251… 337;1   48.1    83.4      337
#> 3 chr10_60847284_… chr10_60871326_60… 33157… 1251… 337;1   48.1    83.4      337
#> 4 chr10_60849980_… chr10_60871326_60… 33157… 1251… 337;1   48.1    83.4      337
#> 5 chr10_60850566_… chr10_60871326_60… 33157… 1251… 337;1   48.1    83.4      337
#> 6 chr10_60852394_… chr10_60871326_60… 33157… 1251… 337;1   48.1    83.4      337
dt%>%
在(vars(HH:NLNL),list(new=~str_split(,“;”)))%%>%
mutate_at(vars(HH_new:NLNL_new),list(~map_dbl(,~as.numeric(.x)%>%{[1]/[2]})))
#>变体id转录本id HH HNL NL HH新HNL新NL新
#>                                         
#>1 chr10_6084247_…chr10_60871326_60…32968…1440…337;1   48.1    72        337
#>2 chr10_60846892_…chr10_60871326_60…33157…1251…337;1   48.1    83.4      337
#>3 chr10_60847284_…chr10_60871326_60…33157…1251…337;1   48.1    83.4      337
#>4 chr10_60849980_…chr10_60871326_60…33157…1251…337;1   48.1    83.4      337
#>5 chr10_6085066_u10_60871326_60…33157…1251…337;1   48.1    83.4      337
#>6 chr10_60852394_…chr10_60871326_60…33157…1251…337;1   48.1    83.4      337

下面是一个基本的R解决方案,使用
strsplit
处理单元格中以分号分隔的值:

df <- cbind(df,`colnames<-`(sapply(c("HH","HNL","NLNL"),
                             function(v) sapply(strsplit(df[,v],split = ";"),
                                                function(x) Reduce("/",as.numeric(x)))),c("HHnew","HNLnew","NLNLnew")))
df$diff <- with(df,NLNLnew - HHnew)
数据

df <- structure(list(variant_id = c("chr10_60842447_A_G_b38", "chr10_60846892_G_A_b38", 
"chr10_60847284_C_T_b38", "chr10_60849980_T_C_b38", "chr10_60850566_A_T_b38", 
"chr10_60852394_C_A_b38"), transcript_id = c("chr10_60871326_60871443", 
"chr10_60871326_60871443", "chr10_60871326_60871443", "chr10_60871326_60871443", 
"chr10_60871326_60871443", "chr10_60871326_60871443"), HH = c("32968;685", 
"33157;690", "33157;690", "33157;690", "33157;690", "33157;690"
), HNL = c("1440;20", "1251;15", "1251;15", "1251;15", "1251;15", 
"1251;15"), NLNL = c("337;1", "337;1", "337;1", "337;1", "337;1", 
"337;1")), class = "data.frame", row.names = c(NA, -6L))

df下面是一个基本的R解决方案,它使用
strsplit
来处理单元格中以分号分隔的值:

df <- cbind(df,`colnames<-`(sapply(c("HH","HNL","NLNL"),
                             function(v) sapply(strsplit(df[,v],split = ";"),
                                                function(x) Reduce("/",as.numeric(x)))),c("HHnew","HNLnew","NLNLnew")))
df$diff <- with(df,NLNLnew - HHnew)
数据

df <- structure(list(variant_id = c("chr10_60842447_A_G_b38", "chr10_60846892_G_A_b38", 
"chr10_60847284_C_T_b38", "chr10_60849980_T_C_b38", "chr10_60850566_A_T_b38", 
"chr10_60852394_C_A_b38"), transcript_id = c("chr10_60871326_60871443", 
"chr10_60871326_60871443", "chr10_60871326_60871443", "chr10_60871326_60871443", 
"chr10_60871326_60871443", "chr10_60871326_60871443"), HH = c("32968;685", 
"33157;690", "33157;690", "33157;690", "33157;690", "33157;690"
), HNL = c("1440;20", "1251;15", "1251;15", "1251;15", "1251;15", 
"1251;15"), NLNL = c("337;1", "337;1", "337;1", "337;1", "337;1", 
"337;1")), class = "data.frame", row.names = c(NA, -6L))
df对拆分列不做任何工作?不做任何工作