首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将具有相同ID的两行从在场/缺勤连接为0,1,2

将具有相同ID的两行从在场/缺勤连接为0,1,2
EN

Stack Overflow用户
提问于 2019-05-14 11:44:20
回答 2查看 92关注 0票数 0

我试图用SNP ID记录原始表的行数,并在列中记录示例ID

到目前为止,我只成功地将数据转换为0和1的存在/缺勤。

我尝试了一些简单的代码来进行进一步的转换,但是找不到我想要的代码。

原来的桌子是这样的

代码语言:javascript
运行
复制
snpID   Cal_X1  Cal_X2  Cal_X3  Cal_X4  Cal_X5  Cal_X6  Cal_X7  Cal_X8
A_001   0   1   1   1   0   0   1   0
A_001   0   0   1   0   1   0   1   1
A_002   1   1   0   1   1   1   0   0
A_002   0   1   1   0   1   0   1   1
A_003   1   0   0   1   0   1   1   0
A_003   1   1   0   1   1   0   0   1
A_004   0   0   1   0   0   1   0   0
A_004   1   0   0   1   0   1   1   0

我想把分数记录到0/0 = NA,0/1 = 0,1/1 = 2,1/0 =1,所以产品看起来是这样的。

代码语言:javascript
运行
复制
snpID   Cal_X1  Cal_X2  Cal_X3  Cal_X4  Cal_X5  Cal_X6  Cal_X7  Cal_X8
A_001   NA         1       2       1       0       NA      2      0
A_002   1          2       0       1       2       1       0      0
A_003   2          0       NA      2       0       1       1      0
A_004   0          NA      1       0       NA      2       0      NA

这只是一个例子。我的总snpID为96000,总样本ID为500。

任何帮助编写这段代码将是非常感谢的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-14 14:41:50

下面是几个dplyr-based示例,每个示例在一个管道中工作,并获得相同的输出。主要的第一步是按ID分组,然后用/折叠所有列。然后,您可以使用mutate_at来选择所有以Cal_开头的列,如果除了您不想对其执行此操作的ID之外还有其他列,则-this可能会很有用。

第一个方法是case_when

代码语言:javascript
运行
复制
library(dplyr)

dat %>%
  group_by(snpID) %>%
  summarise_all(paste, collapse = "/") %>%
  mutate_at(vars(starts_with("Cal_")), ~case_when(
    . == "0/1" ~ 0,
    . == "1/1" ~ 2,
    . == "1/0" ~ 1,
    TRUE ~ NA_real_
  ))
#> # A tibble: 4 x 9
#>   snpID Cal_X1 Cal_X2 Cal_X3 Cal_X4 Cal_X5 Cal_X6 Cal_X7 Cal_X8
#>   <chr>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
#> 1 A_001     NA      1      2      1      0     NA      2      0
#> 2 A_002      1      2      0      1      2      1      0      0
#> 3 A_003      2      0     NA      2      0      1      1      0
#> 4 A_004      0     NA      1      0     NA      2      0     NA

然而,(在我看来) case_when读起来有点棘手,这并不能显示它的真正功能,它可以对多个变量进行if/ its检查。dplyr::recode更适合一次检查一个变量。

代码语言:javascript
运行
复制
dat %>%
  group_by(snpID) %>%
  summarise_all(paste, collapse = "/") %>%
  mutate_at(vars(starts_with("Cal_")), 
            ~recode(., 
                    "0/1" = 0,
                    "1/1" = 2,
                    "1/0" = 1,
                    "0/0" = NA_real_))
# same output as above

或者,为了获得更多的灵活性和可读性,创建一个小的查找对象。这样,您就可以重用重新编码逻辑并轻松地更改它。recode接受一组命名参数;使用tidyeval,您可以传入一个命名向量并与!!! ( recode文档中有一个类似的例子)来改变它:

代码语言:javascript
运行
复制
lookup <- c("0/1" = 0, "1/1" = 2, "1/0" = 1, "0/0" = NA_real_)

dat %>%
  group_by(snpID) %>%
  summarise_all(paste, collapse = "/") %>%
  mutate_at(vars(starts_with("Cal_")), recode, !!!lookup)
# same output
票数 1
EN

Stack Overflow用户

发布于 2019-05-14 12:00:24

您可以使用aggregate连接每个snpID的值,然后根据需要使用来自dplyrcase_when替换值。

代码语言:javascript
运行
复制
(out <- aggregate(.~ snpID, dat, toString))
#  snpID Cal_X1 Cal_X2 Cal_X3 Cal_X4 Cal_X5 Cal_X6 Cal_X7 Cal_X8
#1 A_001   0, 0   1, 0   1, 1   1, 0   0, 1   0, 0   1, 1   0, 1
#2 A_002   1, 0   1, 1   0, 1   1, 0   1, 1   1, 0   0, 1   0, 1
#3 A_003   1, 1   0, 1   0, 0   1, 1   0, 1   1, 0   1, 0   0, 1
#4 A_004   0, 1   0, 0   1, 0   0, 1   0, 0   1, 1   0, 1   0, 0

现在重新编码列

代码语言:javascript
运行
复制
library(dplyr)
out[-1] <- case_when(out[-1] == "0, 0" ~ NA_integer_,
                     out[-1] == "0, 1" ~ 0L,
                     out[-1] == "1, 0" ~ 1L,
                     TRUE ~ 2L)

结果

代码语言:javascript
运行
复制
out
#  snpID Cal_X1 Cal_X2 Cal_X3 Cal_X4 Cal_X5 Cal_X6 Cal_X7 Cal_X8
#1 A_001     NA      1      2      1      0     NA      2      0
#2 A_002      1      2      0      1      2      1      0      0
#3 A_003      2      0     NA      2      0      1      1      0
#4 A_004      0     NA      1      0     NA      2      0     NA

数据

代码语言:javascript
运行
复制
dat <- structure(list(snpID = c("A_001", "A_001", "A_002", "A_002", 
"A_003", "A_003", "A_004", "A_004"), Cal_X1 = c(0L, 0L, 1L, 0L, 
1L, 1L, 0L, 1L), Cal_X2 = c(1L, 0L, 1L, 1L, 0L, 1L, 0L, 0L), 
    Cal_X3 = c(1L, 1L, 0L, 1L, 0L, 0L, 1L, 0L), Cal_X4 = c(1L, 
    0L, 1L, 0L, 1L, 1L, 0L, 1L), Cal_X5 = c(0L, 1L, 1L, 1L, 0L, 
    1L, 0L, 0L), Cal_X6 = c(0L, 0L, 1L, 0L, 1L, 0L, 1L, 1L), 
    Cal_X7 = c(1L, 1L, 0L, 1L, 1L, 0L, 0L, 1L), Cal_X8 = c(0L, 
    1L, 0L, 1L, 0L, 1L, 0L, 0L)), .Names = c("snpID", "Cal_X1", 
"Cal_X2", "Cal_X3", "Cal_X4", "Cal_X5", "Cal_X6", "Cal_X7", "Cal_X8"
), class = "data.frame", row.names = c(NA, -8L))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56129671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档