【问题标题】:Cannot accurately convert from long format to wide in r无法在 r 中准确地从长格式转换为宽格式
【发布时间】:2019-11-04 17:44:08
【问题描述】:

我正在尝试使用以下代码从长格式转换为宽格式。

 data_ige<-read.csv("serology.csv",header = TRUE,na.strings=0)

library(tidyverse) library(magrittr)

data_new <- data_ige %>% spread(test, value)

我有以下数据集 existing dataset

运行代码后,它会转换日期(但不是以我想要的方式),如下图所示,以黄色突出显示的项目表示这些值出现在多行中,但它们应该在第一行而不是一个新的行。每个患者都有 1 次访问或 2 次访问的数据。所以第 1 次访问的所有测试结果,我想在一行中查看它们,并在第二行中查看第 2 次访问的测试结果。

After transformation

此屏幕截图显示了预期的结果。

desired outcome

【问题讨论】:

  • 请使用dput 显示示例而不是图像。你试过library(data.table); dcast(setDT(df1), ID +date ~ test, value.var = 'value')
  • 根据图片,可能你需要data_ige %&gt;% group_by(id, date, test) %&gt;% mutate(rn = row_number()) %&gt;% ungroup %&gt;% spread(test, value)
  • 嗨@akrun,我应用了你的代码,但不幸的是它对我不起作用,观察次数保持不变。我应用了这两个代码。
  • 我根据显示的图像创建了示例,它在下面的解决方案中为我工作

标签: r tidyverse spread


【解决方案1】:

我们需要创建一个序列列,因为有重复

library(dplyr)
library(tidyr)
data_ige %>% 
   group_by(ID, date, test) %>%
   mutate(rn = row_number()) %>%
   ungroup %>%
   spread(test, value) %>%
   #or use pivot_wider as spread is getting deprecated
   #  pivot_wider(names_from = test, values_from = value) %>%
   select(-rn)
# A tibble: 8 x 9
#  ID     date    `1`   `3`   `4`   `5`   `6`   `7`   `8`
#  <fct> <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 A      2008  0.035 NA    NA    NA    NA    NA    NA   
#2 A      2011  2.75  NA    NA    NA    NA    NA    NA   
#3 B      2011  9.99   3.65  0.68  0.02  0.17  0.5  NA   
#4 C      2008  0     NA    NA    NA    NA    NA    NA   
#5 C      2011 NA     NA    NA    NA    NA    NA     0.09
#6 D      2008  0      0     0     0     0     0.59  0   
#7 D      2011  0      0.49  0.2   0.08  0.16  0.5   0.13
#8 D      2011  9.99  NA    NA    NA    NA    NA    NA   

数据

data_ige <- structure(list(ID = structure(c(1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 
3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L), .Label = c("A", "B", "C", "D"), class = "factor"), date = c(2008, 
2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2008, 2011, 2008, 
2008, 2008, 2008, 2008, 2008, 2008, 2011, 2011, 2011, 2011, 2011, 
2011, 2011), test = c(1, 1, 1, 3, 4, 5, 6, 7, 8, 1, 1, 1, 3, 
4, 5, 6, 7, 8, 1, 3, 4, 5, 6, 7, 8), value = c(0.035, 2.75, 9.99, 
3.65, 0.68, 0.02, 0.17, 0.5, 0.09, 0, 0, 0, 0, 0, 0, 0, 0.59, 
0, 9.99, 0.49, 0.2, 0.08, 0.16, 0.5, 0.13)), 
class = "data.frame", row.names = c(NA, 
-25L))

【讨论】:

    【解决方案2】:

    当我使用您链接到的表格时,它实际上对我来说很好。您的数据可能存在问题,即您可能已导入字符串作为因素或类似因素。试试我在下面提供的数据:

    data_ige %>% spread(test, value)
    
    #### OUTPUT ####
    
      ID date     1    3    4    5    6    7    8
    1  A 2008 0.035   NA   NA   NA   NA   NA   NA
    2  A 2011 2.750   NA   NA   NA   NA   NA   NA
    3  B 2011 9.990 3.65 0.68 0.02 0.17 0.50 0.09
    4  C 2008 0.000   NA   NA   NA   NA   NA   NA
    5  C 2011 0.000   NA   NA   NA   NA   NA   NA
    6  D 2008 0.000 0.00 0.00 0.00 0.00 0.59 0.00
    7  D 2011 9.990 0.49 0.20 0.08 0.16 0.50 0.13
    

    您可能想要做的一件事是为test == 2 添加一行,这不在您的数据中。这样,您将获得一个只有 NAs 的列 2,就像您链接到的数据框的图像一样:

    data_ige %>%
        add_row(ID = "A", date = 2008, test = 2) %>% 
        spread(test, value)
    
    #### OUTPUT ####
    
      ID date     1  2    3    4    5    6    7    8
    1  A 2008 0.035 NA   NA   NA   NA   NA   NA   NA
    2  A 2011 2.750 NA   NA   NA   NA   NA   NA   NA
    3  B 2011 9.990 NA 3.65 0.68 0.02 0.17 0.50 0.09
    4  C 2008 0.000 NA   NA   NA   NA   NA   NA   NA
    5  C 2011 0.000 NA   NA   NA   NA   NA   NA   NA
    6  D 2008 0.000 NA 0.00 0.00 0.00 0.00 0.59 0.00
    7  D 2011 9.990 NA 0.49 0.20 0.08 0.16 0.50 0.13
    

    这是我使用的数据框:

    data_ige <- structure(list(ID = c("A", "A", "B", "B", "B", "B", "B", "B", 
    "B", "C", "C", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", 
    "D", "D", "D", "D"), date = c(2008L, 2011L, 2011L, 2011L, 2011L, 
    2011L, 2011L, 2011L, 2011L, 2008L, 2011L, 2008L, 2008L, 2008L, 
    2008L, 2008L, 2008L, 2008L, 2011L, 2011L, 2011L, 2011L, 2011L, 
    2011L, 2011L), test = c(1L, 1L, 1L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 
    1L, 1L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 3L, 4L, 5L, 6L, 7L, 8L), 
        value = c(0.035, 2.75, 9.99, 3.65, 0.68, 0.02, 0.17, 0.5, 
        0.09, 0, 0, 0, 0, 0, 0, 0, 0.59, 0, 9.99, 0.49, 0.2, 0.08, 
        0.16, 0.5, 0.13)), class = "data.frame", row.names = c(NA, 
    -25L))
    

    【讨论】:

    • 嗨@LaLa,我不知道原因,但它对我不起作用我的数据集中有 6253 行,当我应用行时保持不变。你能建议我应该检查什么吗?
    • @bushra 你能用dput(data_ige[sample.int(nrow(data_ige), 50),])给我们你的数据样本吗?只需将输出(以 structure(... 开头)粘贴到原始问题中即可。
    • 结构(列表(ID = c(628L, 6028L, 5441L, 3823L, 4038L, 859L, 6158L, 2306L, 6284L, 5175L, 2769L, 3612L, 6209L, 624525, 15233L, 6, 6 1675L,2141L,2608L,1937L,5281L,4787L,3804L,647L,846L,1229L,3185L,2110L,2402L,5346L,657​​L,162L,5116L,2952L,981L,1439L,1607L,1193L,2467L,6160L,2669L, 3582L,5422L,2124L,4418L,2469L,4052L,747L,5140L),EPID = C(4900213L,200372L,501602L,500259L,1801101L,501204L,200499L,3901166L,200625L,4801248L,500050L,4800935L,200545L,200559L,4800631L ,
    • 结果很长,我不能在这里粘贴。这只是我粘贴的简短部分。
    • @bushra 您应该将输出 structure(…) 添加到您的原始问题中,而不是 cmets。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-25
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 2015-07-18
    相关资源
    最近更新 更多