r中的dcast具有重复项且无聚合

r中的dcast具有重复项且无聚合,r,data-cleaning,R,Data Cleaning,我在这里看过许多类似的问题,但找不到解决这种情况的答案。我的数据框如下所示: SET SP T1 T2 T3 A dog 1 0 0 A cat 0 NA 4 A bird 5 0 NA B cat 2 0 0 B bird NA 3 0 C dog 1 0 0 C cat 0 0 6 C bird 0 0 0 D dog NA 22 1 其中SET故意重复多次,每个记录包括一个SP和多个试验

我在这里看过许多类似的问题,但找不到解决这种情况的答案。我的数据框如下所示:

SET SP   T1  T2  T3
A   dog  1  0   0
A   cat  0  NA  4
A   bird 5  0   NA
B   cat  2  0   0
B   bird NA 3   0
C   dog  1  0   0
C   cat  0  0   6
C   bird 0  0   0
D   dog  NA 22  1
其中SET故意重复多次,每个记录包括一个SP和多个试验的值(T1-3)

我想要的是如下所示的宽数据帧。不得进行任何类型的求和/平均/数学运算:

SET DOG_T1  DOG_T2  DOG_T3  CAT_T1  CAT_T2  CAT_T3  BIRD_T1 BIRD_T2 BIRD_T3
142   1     0       0      0        NA      4       5       0       NA
255  NA     NA     NA      2        0       0       NA      3       0
336   1     0      0       0        0       6       0       0       0
66   NA    22      1       NA       NA      NA      NA      NA      NA
我尝试了以下操作,但收到melt和dcast默认为长度的错误。这会将设置的变量转换为不同的数字,并且只为值填充0和1

df%>%
分组依据(集合,SP)%>%
熔化(id.vars=c('SET','SP'))%>%
data.table::dcast(SP+variable~SET,fun.aggregate=NULL,value.var='value')
当我没有任何重复集时,这可以工作,但当我包含完整的数据集时就会失败。 注意:我的实际数据帧大约有250万行,所以速度很重要。

您可以试试

library(tidyverse)
df <- read.table(header=T, text="
SET SP   T1  T2  T3
A   dog  1  0   0
A   cat  0  NA  4
A   bird 5  0   NA
B   cat  2  0   0
B   bird NA 3   0
C   dog  1  0   0
C   cat  0  0   6
C   bird 0  0   0
D   dog  NA 22  1")
df %>% 
  gather(var, val, -(1:2)) %>% 
  unite("SP", SP, var) %>% 
  spread(SP, val)
#   SET bird_T1 bird_T2 bird_T3 cat_T1 cat_T2 cat_T3 dog_T1 dog_T2 dog_T3
# 1   A       5       0      NA      0     NA      4      1      0      0
# 2   B      NA       3       0      2      0      0     NA     NA     NA
# 3   C       0       0       0      0      0      6      1      0      0
# 4   D      NA      NA      NA     NA     NA     NA     NA     22      1
库(tidyverse)
df%
聚集(var,val,-(1:2))%>%
单位(“SP”,SP,var)%>%
价差(SP、val)
#设置鸟\u T1鸟\u T2鸟\u T3猫\u T1猫\u T2猫\u T3狗\u T1狗\u T2狗\u T3
#1A50NA0NA4100
#2bNA3020NANA
#3C0006100
#4 D NA NA NA NA 22 1
您可以试试

library(tidyverse)
df <- read.table(header=T, text="
SET SP   T1  T2  T3
A   dog  1  0   0
A   cat  0  NA  4
A   bird 5  0   NA
B   cat  2  0   0
B   bird NA 3   0
C   dog  1  0   0
C   cat  0  0   6
C   bird 0  0   0
D   dog  NA 22  1")
df %>% 
  gather(var, val, -(1:2)) %>% 
  unite("SP", SP, var) %>% 
  spread(SP, val)
#   SET bird_T1 bird_T2 bird_T3 cat_T1 cat_T2 cat_T3 dog_T1 dog_T2 dog_T3
# 1   A       5       0      NA      0     NA      4      1      0      0
# 2   B      NA       3       0      2      0      0     NA     NA     NA
# 3   C       0       0       0      0      0      6      1      0      0
# 4   D      NA      NA      NA     NA     NA     NA     NA     22      1
库(tidyverse)
df%
聚集(var,val,-(1:2))%>%
单位(“SP”,SP,var)%>%
价差(SP、val)
#设置鸟\u T1鸟\u T2鸟\u T3猫\u T1猫\u T2猫\u T3狗\u T1狗\u T2狗\u T3
#1A50NA0NA4100
#2bNA3020NANA
#3C0006100
#4 D NA NA NA NA 22 1

这是一种
dcast.data.table
非常出色的情况。它允许多个参数作为“value.var”,允许非常简洁的语法:

library(data.table)
dcast(df, SET ~ SP, value.var=c("T1", "T2", "T3"))
#   SET T1_bird T1_cat T1_dog T2_bird T2_cat T2_dog T3_bird T3_cat T3_dog
#1:   A       5      0      1       0     NA      0      NA      4      0
#2:   B      NA      2     NA       3      0     NA       0      0     NA
#3:   C       0      0      1       0      0      0       0      6      0
#4:   D      NA     NA     NA      NA     NA     22      NA     NA      1

在这种情况下,
dcast.data.table
。它允许多个参数作为“value.var”,允许非常简洁的语法:

library(data.table)
dcast(df, SET ~ SP, value.var=c("T1", "T2", "T3"))
#   SET T1_bird T1_cat T1_dog T2_bird T2_cat T2_dog T3_bird T3_cat T3_dog
#1:   A       5      0      1       0     NA      0      NA      4      0
#2:   B      NA      2     NA       3      0     NA       0      0     NA
#3:   C       0      0      1       0      0      0       0      6      0
#4:   D      NA     NA     NA      NA     NA     22      NA     NA      1

根据上面的@lukeA,但在
dcast()中添加
fun.aggregate=identity
fun.aggregate=list
参数,在
dcast()中添加
fun.aggregate=identity
fun.aggregate=list
参数
函数调用

由于我目前的声誉不允许在上面的@lukeA answer中添加评论,我将此作为一个新的答案,这更像是一个建议:

使用
data.table
函数
setcolorder
可以使用类似的自定义函数将列重新排序为“bird_T1、cat_T1、dog_T1、bird_T2、cat_T2等”

newOrder <- function() {

      lapply(1:max(index)
             , function(i) grep(
                                 sprintf('%s', i)
                                           , names(DT), value = TRUE)
        )}

最后,以常规方式实现新秩序:

setcolorder(dcast(DT), neworder = newOrder())


由于我目前的声誉不允许在上面的@lukeA-answer中添加评论,因此我将此作为一个更具建议性的新答案:

使用
data.table
函数
setcolorder
可以使用类似的自定义函数将列重新排序为“bird_T1、cat_T1、dog_T1、bird_T2、cat_T2等”

newOrder <- function() {

      lapply(1:max(index)
             , function(i) grep(
                                 sprintf('%s', i)
                                           , names(DT), value = TRUE)
        )}

最后,以常规方式实现新秩序:

setcolorder(dcast(DT), neworder = newOrder())


谢谢你的回复。在您的示例中,“var”和“val”是我上面描述的melt语句的变量和值结果,还是其他?var是变量,包含t1到t3,val是相应列中的值。更新:我能够运行此操作,但它在集合中抛出了一个关于我的重复标识符的错误。通过将最后一行从spread()更改为restrape:
df%>%gather(var,val,-(7:8))%%>%unite(“SP”,SP,var)%%>%restrape(idvar='SET',timevar='SP',direction='wide')
感谢您的回复。在您的示例中,“var”和“val”是我上面描述的melt语句的变量和值结果,还是其他?var是变量,包含t1到t3,val是相应列中的值。更新:我能够运行此操作,但它在集合中抛出了一个关于我的重复标识符的错误。通过将最后一行从spread()更改为restrape:
df%>%gather(var,val,-(7:8))%%>%unite(“SP”,SP,var)%%>%restrape(idvar='SET',timevar='SP',direction='wide')
感谢您的回复。但是,这仍然会导致“默认为长度”错误。我在上面的熔化步骤前后都试过了。我同意dcast应该可以在这里工作(从我所读到的),但似乎无法实现它。这不是一个错误,而是一个警告。数据中有重复项。当有两个条目的集合A、T1和bird时,您想做什么?正如您在上面看到的,该条目只有一个插槽,这就是摘要所做的。您希望这些值相加吗?平均值?等等…谢谢你的回复。但是,这仍然会导致“默认为长度”错误。我在上面的熔化步骤前后都试过了。我同意dcast应该可以在这里工作(从我所读到的),但似乎无法实现它。这不是一个错误,而是一个警告。数据中有重复项。当有两个条目的集合A、T1和bird时,您想做什么?正如您在上面看到的,该条目只有一个插槽,这就是摘要所做的。您希望这些值相加吗?平均值?等