如何根据因子创建多向表?

How to create multiway tables based on factors?

我一直在尝试根据因子数据创建包含结果的多向表。

我的数据如下:

Trial    Room    Mechanism    Result
A        1       Straight     0,5
A        1       Bendy        0,2
A        2       Straight     0.7
A        2       Bendy        0.3
B        1       Straight     0.6
B        1       Bendy        0.2
B        2       Straight     0.6
B        2       Bendy        0.2

实际上有大约 6 个因素,具有多个水平和一列结果。

我要找的结果是这样的:

           Room 1      Room 2   
           A    B      A     B   
Straight  0.5   0.6    0.7   0.6
Bendy     0.2   0.2    0.3   0.2


是否有执行此操作的函数或程序包?

所有搜索结果都产生了代码,可以根据 data.table() 或 count() 等因素制作多路频率表。这不是我要找的。也许我使用了错误的关键词,或者可能有更多关于该问题的信息。

手动进行此操作是一种选择,但不是首选。而且我不是第一个需要这样做的人,所以我知道有办法!

无法找到合适的复制品,所以这就是您散布和重新排序列的方式。诀窍是将 RoomTrial 变量都指定为输出列。 tidyr 的新函数集 pivot_wider/pivot_longer 使这变得特别容易。传播后,一个简单的正则表达式可以帮助您将列排序为您需要的格式,即

library(dplyr)
library(tidyr)

df %>% 
 pivot_wider(id_cols = Mechanism, names_from = c(Room, Trial), values_from = Result) %>% 
 select(1, order(sub('_.*', '', names(.))))

这给出了,

# A tibble: 2 x 5
  Mechanism `1_A` `1_B` `2_A` `2_B`
  <fct>     <fct> <fct> <fct> <fct>
1 Straight  0,5   0.6   0.7   0.6  
2 Bendy     0,2   0.2   0.3   0.2  

这里是 data.table 版本 dcast

library(data.table)
dcast(setDT(df), Mechanism~paste0('Room', Room) + Trial, value.var = 'Result')

#   Mechanism Room1_A Room1_B Room2_A Room2_B
#1:     Bendy     0,2     0.2     0.3     0.2
#2:  Straight     0,5     0.6     0.7     0.6

这是一个基本的 R 解决方案,其中 reshape() 用于重新格式化您的数据框

df <- df[with(df,order(Room,Trial)),]
dfout <- reshape(within(df,RT <- apply(df[1:2],1,paste0,collapse = ""))[-(1:2)],
                 idvar = "Mechanism",
                 timevar = "RT",
                 direction = "wide")

这样

> dfout
  Mechanism Result.A1 Result.B1 Result.A2 Result.B2
1  Straight       0.5       0.6       0.7       0.6
2     Bendy       0.2       0.2       0.3       0.2

数据

df <- structure(list(Trial = c("A", "A", "B", "B", "A", "A", "B", "B"
), Room = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), Mechanism = c("Straight", 
"Bendy", "Straight", "Bendy", "Straight", "Bendy", "Straight", 
"Bendy"), Result = c(0.5, 0.2, 0.6, 0.2, 0.7, 0.3, 0.6, 0.2)), row.names = c(1L, 
2L, 5L, 6L, 3L, 4L, 7L, 8L), class = "data.frame")