R 将具有相同ID的两行从存在/不存在连接为0,1,2

R 将具有相同ID的两行从存在/不存在连接为0,1,2,r,subset,R,Subset,我试图记录一个原始表,行中有SNP ID,列中有SampleID 到目前为止,我仅使用0和1将数据转换为存在/不存在 我尝试了一些简单的代码来做进一步的转换,但找不到一个我想要的 原来的桌子是这样的 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_0

我试图记录一个原始表,行中有
SNP ID
,列中有Sample
ID

到目前为止,我仅使用0和1将数据转换为存在/不存在

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

原来的桌子是这样的

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,所以产品看起来像这样

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


编写此代码的任何帮助都将不胜感激。

您可以使用
aggregate
将每个
snpID
的值串联起来,然后在
dplyr
中的
case\u的帮助下根据需要替换这些值

(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
数据

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))

dat这里有几个基于
dplyr
的示例,每个示例在单个管道中工作,并获得相同的输出。主要的第一步是按ID分组,然后用
/
折叠所有列。然后,您可以使用
mutate\u at
选择以
Cal\u
开头的所有列-如果您不想对ID以外的其他列执行此操作,这可能会很有用

第一种方法是
情况下的

库(dplyr)
dat%>%
分组依据(snpID)%>%
总结所有内容(粘贴、折叠=“/”)%>%
在(vars)处变异(以(“Cal”)开头),在(
. == "0/1" ~ 0,
. == "1/1" ~ 2,
. == "1/0" ~ 1,
真的~NA_real_
))
#>#tibble:4 x 9
#>snpID校准X1校准X2校准X3校准X4校准X5校准X6校准X7校准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
然而,(在我看来)
case\u when
读起来有点棘手,这并没有显示出它的真正威力,即对多个变量进行if/else检查。更适合一次检查一个变量的是
dplyr::recode

dat%>%
分组依据(snpID)%>%
总结所有内容(粘贴、折叠=“/”)%>%
在(vars)处变异(以(“Cal”)开头),
~重新编码(。,
"0/1" = 0,
"1/1" = 2,
"1/0" = 1,
“0/0”=不真实(真实)
#输出同上
或者,为了获得更大的灵活性和可读性,创建一个小的查找对象。这样,您就可以重用重新编码逻辑并轻松地对其进行更改
recode
接受一组命名参数;使用tidyeval,您可以传入一个命名向量,并使用
将其取消(在
重新编码
文档中有一个类似的示例):

lookup%
分组依据(snpID)%>%
总结所有内容(粘贴、折叠=“/”)%>%
在(变量(以(“校准”)开始)、重新编码、!!!查找)处进行变异
#相同输出

请注意,您的预期输出中有一些输入错误。已修复。好地方。谢谢马库斯!很乐意帮忙。如果他们让你高兴,请考虑其中一个答案。欢呼-1索引背后的逻辑是什么?@camille这是因为
snpID
列。我想,如果没有……可能会起作用。啊,如果没有它,我们将使用另一个案例a la
out==“1,1”~2L
TRUE~out$snpID
,这样我们可能会节省一些字符。我不确定当
时,您的最后一个选项是否比
case\u更具可读性(
!!/code>使应用/记住IMHO变得很困难),但肯定是一个好的答案。我尽可能多地使用
baseR
,并认为
case\u当
与多个嵌套的
ifelse
相比会增加可读性时,没有任何东西比4个嵌套的
ifelse
s更好!对我来说,当所有值都来自一个地方时,像
recode
fct\u recode
这样的东西更有意义。如果有类似于查找表的功能,我喜欢在我进入一个更大的项目后将其放在一个单独的变量中,我想看看在哪里声明类似的内容,并访问它以重用。但这完全是偏好和背景的问题。我可能有更多的
case\u,当每天的情况下,我实际上需要再问一个问题。我使用了第二个代码,得到了这样一个警告:“被视为NA as.x的未替换值不兼容。请详尽地指定替换或提供.default”。这些数据在我看来很好,但我不能看得一清二楚。我寻找解决方案并尝试改变“to”并在recode前面添加了dplyr::但仍然得到相同的警告。有什么帮助吗?我想这意味着在您的数据中有一些值不在查找范围内。也可能是您正在用
NA
-
NA
替换实际键入的值,这就是为什么我使用
NA\u real\u
来确保它被解释为数值是的,我在重新编码之前在dat中有NAs。谢谢你,卡米尔!
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
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))