我有一个形式叫df的小标题:

sample  nuclide  intensity
SRM1    Pb206    200
SRM1    Pb207    250
SRM1    Pb208    301
SRM1    Pb206    202
SRM1    Pb207    254
SRM1    Pb208    305
SAM1    Pb206    154
SAM1    Pb207    262
SAM1    Pb208    311
SAM1    Pb206    157
SAM1    Pb207    261
SAM1    Pb208    325


它可以通过以下方式生成:

df <- tbl_df(
data.frame(sample = rep(c("SRM1", "SAM1"), each = 6),
nuclide = rep(c("Pb206", "Pb207", "Pb208"), 4),
intensity = c(200, 250, 301, 202, 254, 305, 154, 262, 311, 157, 261, 325)))


我想重新安排它

sample  Pb208  Pb207  Pb206
SRM1    301    250    200
SRM1    305    254    202
SAM1    311    262    157
SAM1    325    261    204


我使用以下方法尝试了tidyr软件包:

df %>%
  select(sample, nuclide, intensity) %>%
  group_by(sample) %>%
  mutate(row = 1:n()) %>%
  spread(nuclide, intensity) %>% select(-row)


但是它产生了不想要的NA的结果。

非常重要的是,在转换期间,数据集中的样本名称应保留其原始顺序,并且不使用聚合函数。特别是第一个条件是使我的问题与之前发布的其他类似问题不同。

然后,该解决方案将应用于具有超过20000行的更大的数据集。

最佳答案

使用:

lvls <- as.character(unique(df$sample))

library(tidyverse) # this will load 'dplyr' and 'tidyr' among others
df %>%
  group_by(sample, nuclide) %>%
  mutate(id = row_number()) %>%
  spread(nuclide, intensity) %>%
  ungroup() %>%                             # needed to be able to modify the 'sample' variable
  mutate(sample = factor(sample, levels = lvls)) %>%
  arrange(sample) %>%
  select(sample, Pb208:Pb206)


给出:

  sample Pb208 Pb207 Pb206
  (fctr) (dbl) (dbl) (dbl)
1   SRM1   301   250   200
2   SRM1   305   254   202
3   SAM1   311   262   154
4   SAM1   325   261   157


或者(如果您只想按降序排列):

df %>%
  group_by(sample, nuclide) %>%
  mutate(id = row_number()) %>%
  spread(nuclide, intensity) %>%
  arrange(desc(sample)) %>%
  select(sample, Pb208:Pb206)




使用data.table的替代方法:

library(data.table)
dcast(setDT(df), sample + rowid(sample, nuclide) ~ nuclide,
      value.var = 'intensity')[, sample := factor(sample, levels = lvls)
                               ][order(sample)]

08-17 04:42
查看更多