如何找到与R数据帧中的字符串关联的两行并减去它们的相互列值

时间:2018-10-18 17:24:18

标签: r dataframe

在R中,我有一个看起来像这样的数据框:

    sample  value  gene  tag       isPTV
1   1120    3.4    arx1  1120|arx1  0
2   2123    2.3    mnf2  2123|mnf2  0
3   1129    1.9    trf4  1129|trf4  0
4   2198    0.2    brc1  2198|brc1  0
5   1120    2.1    arx1  1120|arx1  1
6   2123    0.4    mnf2  2123|mnf2  1
7   1129    1.2    trf4  1129|trf4  1
8   2198    0.9    brc1  2198|brc1  1

0表示false,而1表示true。我最终要尝试做的是创建一个数据框,对于每个tag,找到一个value数字之间的绝对值。

例如,1129|trf4出现在两个单独的行中。何时有isPTV有一个值,有的时候没有,因此绝对值为1.9-1.2 = 0.7

我首先尝试编写一个函数来为给定的tag值执行这些操作,这样,对于给定的标签,它将返回包含该标签的两行:

getExprValue <- function(dataframe, tag){
  return(dataframe[tag,])
}

但是这不起作用,而且我对如何在R中索引数据帧不是很熟悉。

正确的方法是什么?

更新:

解决方案1尝试:

m_diff <- m %>% group_by(tag) %>% mutate(absDiff = abs(diff(value)))

响应:

Error in mutate_impl(.data, dots) : Column absDiff must be length 1 (the group size), not 0

解决方案2尝试:

with(df1, abs(ave(value, tag, FUN = diff)))

响应:

Error in x[i] <- value[[j]] : replacement has length zero

1 个答案:

答案 0 :(得分:0)

编辑:我刚刚注意到@akrun有一个简单得多的解决方案

创建具有与您相似的结构的数据:

library(tidyverse)

dat <- tibble(
  sample = rep(sample(1000:3000, 10), 2),
  value = rnorm(20, 5, 1),
  gene = rep(letters[1:10], 2),
  tag = paste(sample, gene, sep = "|"),
  isPTV = rep(0:1, each = 10)
)

dat

#> # A tibble: 20 x 5
#>    sample value gene  tag    isPTV
#>     <int> <dbl> <chr> <chr>  <int>
#>  1   2149  5.90 a     2149|a     0
#>  2   1027  5.46 b     1027|b     0
#>  3   1103  5.65 c     1103|c     0
#>  4   1884  4.86 d     1884|d     0
#>  5   2773  5.58 e     2773|e     0
#>  6   2948  6.98 f     2948|f     0
#>  7   2478  5.17 g     2478|g     0
#>  8   2724  6.71 h     2724|h     0
#>  9   1927  5.06 i     1927|i     0
#> 10   1081  4.39 j     1081|j     0
#> 11   2149  4.60 a     2149|a     1
#> 12   1027  2.97 b     1027|b     1
#> 13   1103  6.17 c     1103|c     1
#> 14   1884  5.83 d     1884|d     1
#> 15   2773  4.23 e     2773|e     1
#> 16   2948  6.48 f     2948|f     1
#> 17   2478  5.06 g     2478|g     1
#> 18   2724  5.32 h     2724|h     1
#> 19   1927  7.32 i     1927|i     1
#> 20   1081  4.73 j     1081|j     1

@akrun解决方案(比我的要好得多):

dat %>%
  group_by(tag) %>%
  mutate(absDiff = abs(diff(value)))

#> # A tibble: 20 x 6
#> # Groups:   tag [10]
#>    sample value gene  tag    isPTV absDiff
#>     <int> <dbl> <chr> <chr>  <int>   <dbl>
#>  1   2149  5.90 a     2149|a     0   1.30 
#>  2   1027  5.46 b     1027|b     0   2.49 
#>  3   1103  5.65 c     1103|c     0   0.520
#>  4   1884  4.86 d     1884|d     0   0.974
#>  5   2773  5.58 e     2773|e     0   1.34 
#>  6   2948  6.98 f     2948|f     0   0.502
#>  7   2478  5.17 g     2478|g     0   0.114
#>  8   2724  6.71 h     2724|h     0   1.39 
#>  9   1927  5.06 i     1927|i     0   2.26 
#> 10   1081  4.39 j     1081|j     0   0.337
#> 11   2149  4.60 a     2149|a     1   1.30 
#> 12   1027  2.97 b     1027|b     1   2.49 
#> 13   1103  6.17 c     1103|c     1   0.520
#> 14   1884  5.83 d     1884|d     1   0.974
#> 15   2773  4.23 e     2773|e     1   1.34 
#> 16   2948  6.48 f     2948|f     1   0.502
#> 17   2478  5.06 g     2478|g     1   0.114
#> 18   2724  5.32 h     2724|h     1   1.39 
#> 19   1927  7.32 i     1927|i     1   2.26 
#> 20   1081  4.73 j     1081|j     1   0.337

我最初的建议(不必要地复杂):

nested <- dat %>%
  group_by(tag) %>%
  nest()

nested %>%
  mutate(difference = map(data, ~ abs(diff(.$value)))) %>%
  select(- data) %>% 
  unnest()

#> # A tibble: 10 x 2
#>    tag    difference
#>    <chr>       <dbl>
#>  1 2149|a      1.30 
#>  2 1027|b      2.49 
#>  3 1103|c      0.520
#>  4 1884|d      0.974
#>  5 2773|e      1.34 
#>  6 2948|f      0.502
#>  7 2478|g      0.114
#>  8 2724|h      1.39 
#>  9 1927|i      2.26 
#> 10 1081|j      0.337