r - 如何使用 map() 将分组索引添加到数据框列?

标签 r tidyr tidyverse purrr

我的数据有两个不同组的两次测量,每个组都有多个样本。我的简单版本有 6 个样本,每个样本如下所示:

library(tidyverse)

df <- tibble(group = c(rep("group_A", 12), rep("group_B", 12)),
         sample = rep(1:6, 4),
         measurement = rep(c(rep("meas_A", 6), rep("meas_B", 6)), 2), 
         value = round(runif(24, min = 0, max = 60)))

但由于测量是在不同条件下重复进行的,因此它实际上是列表中表示的一系列相似的数据帧:

df2 <- bind_rows(df,df,df,df) %>% 
  mutate(condition = c(rep("One", 24), rep("Two", 24), 
                       rep("Three", 24), rep("Four", 24))) %>% 
  unite(group_meas, group, measurement) %>% 
  nest(-condition) 

最终,我想将每个数据帧 reshape 为宽格式,以便可以轻松地从单列中提取每组两个测量值的向量以进行统计比较。例如:

df %>% unite(group_meas, group, measurement) 
  %>%  spread(group_meas, value)

可以像这样沿着列表向下映射:

df2 %>% mutate(data = map(data, ~spread(.x, group_meas, value))) 

当多次测量样本时,就会出现问题,然后 spread() 不起作用,因为有

Duplicate identifiers for rows

我认为解决此问题的最佳方法是添加一个在组合组/测量上分组的新索引列,这将提供唯一的行标识符。这适用于单个数据框。

df %>% unite(group_meas, group, measurement) %>% 
  group_by(group_meas) %>% 
  mutate(gr_m_index = row_number())

但是我无法缩放它来映射列表。

df2 %>% mutate(data = map(data, ~  group_by(.x, group_meas) %>% 
                            mutate(gr_m_index = row_number())))

我认为这一定是一件 tidyeval 的事情,因为我收到以下错误,表明它在错误的位置查找。

Evaluation error: Column gr_m_index must be length 24 (the number of rows) or one, not 4.

如何使用 map() 将分组索引添加到数据框列?

最佳答案

据我了解,根据错误消息,row_number() 返回c(1, 2, 3, 4)。这是因为行数是根据 df2 计算的,而不是嵌套数据帧。

以下任一方法都应该有效:

方法 1。定义所有要映射为独立函数的转换。

index_spread <- function(data){
  return(data %>% 
           group_by(group_meas) %>% 
           mutate(gr_m_index = row_number()) %>%
           spread(group_meas, value))
}

df2 %>% mutate(data = map(data, index_spread)) %>% unnest()

# A tibble: 24 x 7
   condition sample gr_m_index group_A_meas_A group_A_meas_B group_B_meas_A group_B_meas_B
       <chr>  <int>      <int>          <dbl>          <dbl>          <dbl>          <dbl>
 1       One      1          1             12             43             39             52
 2       One      2          2             11             60              8             20
 3       One      3          3             41             23             16             29
 4       One      4          4             23             47             23             36
 5       One      5          5             46             56              1             30
 6       One      6          6             30             13             23             11
 7       Two      1          1             12             43             39             52
 8       Two      2          2             11             60              8             20
 9       Two      3          3             41             23             16             29
10       Two      4          4             23             47             23             36
# ... with 14 more rows

方法 2。对df2$data执行转换,并将转换后的数据帧列表分配回原始数据帧。

df2$data <- map(df2$data, ~group_by(.x, group_meas) %>% 
                  mutate(gr_m_index = row_number()) %>%
                  spread(group_meas, value))
df2 %>% unnest()

# (same output as above)

关于r - 如何使用 map() 将分组索引添加到数据框列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46167773/

相关文章:

r - 如何在 R 中的 PAM 中获取主成分数据

r - 转换纬度和经度

在嵌套的 tibble 上使用 select 时保留嵌套变量

r - 如何在 R 中转置时间序列数据,以便日期变量最终成为新变量名称

r - 选择除一列之外的所有重复行

r - 如何根据 R 中的类别计算列中值的数量?

r - str_replace_all 按位置,应用于向量

r - ggplot中具有最小值和最大值的连续色标

r - 使用 vroom 在 R 中部分读取非常大的 csv.gz

r - 使用成对的相关列(dplyr、tidyr、data.table)