在 dcast 中对列进行排序

shu*_*shi 3 r reshape2 dcast

使用 dcast 时,如何根据列“Col”指定列顺序?

df <- dcast(x, ID ~ ColumnName, value.var = "Answer")
Run Code Online (Sandbox Code Playgroud)

我需要解决方案不特定于数据,因为 x 可以是任何问题的结果(因此 Col 可以是 1-3 或 1-2 等)。下面是 x 的两个虚拟示例。

ID        Answer        ColumnName        Col
1         Anduin        First Name        1
1         Wrynn         Surname           2
1         Alliance      Faction           3
2         Sylvanas      First Name        1
2         Windrunner    Surname           2
2         Horde         Faction           3



ID        Answer        ColumnName        Col
1         The Kirin Tor Quest             1
1         90            Level             2
2         Emissary      Quest             1
2         38            Level             2
Run Code Online (Sandbox Code Playgroud)

Uwe*_*Uwe 9

它没有得到很好的记录,既不是 inhelp("dcast", "reshape2")也不是 inhelp("dcast", "data.table")但列是按因子级别排序的,如果ColumnName是一个因子。

没有 factor()

列按字母顺序排列,这不符合中指定的顺序 Col

reshape2::dcast(x, ID ~ ColumnName, value.var = "Answer")
Run Code Online (Sandbox Code Playgroud)
  ID  Faction First Name    Surname
1  1 Alliance     Anduin      Wrynn
2  2    Horde   Sylvanas Windrunner
Run Code Online (Sandbox Code Playgroud)

因子水平按外观排序

显然,OP正在按照出现的顺序Col编号ColumnName。因此,Col是多余的,可以忽略。

有几种方法可以直接在 的公式中创建按外观排序的因子水平dcast()

基础R

reshape2::dcast(x1, ID ~ factor(ColumnName, levels = unique(ColumnName)), value.var = "Answer")
Run Code Online (Sandbox Code Playgroud)
  ID First Name    Surname  Faction
1  1     Anduin      Wrynn Alliance
2  2   Sylvanas Windrunner    Horde
Run Code Online (Sandbox Code Playgroud)
reshape2::dcast(x2, ID ~ factor(ColumnName, levels = unique(ColumnName)), value.var = "Answer")
Run Code Online (Sandbox Code Playgroud)
  ID         Quest Level
1  1 The Kirin Tor    90
2  2      Emissary    38
Run Code Online (Sandbox Code Playgroud)

根据 OP 的要求,该解决方案并非特定于数据。

forcats

forcats包有一些方便的功能来处理因素。as_factor()按照它们出现的顺序创建级别:

reshape2::dcast(x1, ID ~ forcats::as_factor(ColumnName), value.var = "Answer")
Run Code Online (Sandbox Code Playgroud)

(结果和上面一样。)

为了使代码更明确,fct_inorder()可以使用:

reshape2::dcast(x1, ID ~ forcats::fct_inorder(ColumnName), value.var = "Answer")
Run Code Online (Sandbox Code Playgroud)

因子水平按以下顺序排序 Col

如果请求的列顺序与出现顺序不同,则可以按从 派生的因子水平对列进行排序Col。为了演示,使用了修改后的示例数据集。

以 R 为基数,

reshape2::dcast(x3, ID ~ reorder(factor(ColumnName), Col), value.var = "Answer")
Run Code Online (Sandbox Code Playgroud)
  ID    Surname  Faction First Name
1  1      Wrynn Alliance     Anduin
2  2 Windrunner    Horde   Sylvanas
Run Code Online (Sandbox Code Playgroud)

或与 forcats

reshape2::dcast(x3, ID ~ forcats::fct_reorder(ColumnName, Col), value.var = "Answer")
Run Code Online (Sandbox Code Playgroud)

数据

x1 <- readr::read_table(
"ID        Answer        ColumnName        Col
1         Anduin        First Name        1
1         Wrynn         Surname           2
1         Alliance      Faction           3
2         Sylvanas      First Name        1
2         Windrunner    Surname           2
2         Horde         Faction           3")

x2 <- data.table::fread(
'ID        Answer           ColumnName        Col 
1         "The Kirin Tor"  Quest             1 
1         90               Level             2 
2         Emissary         Quest             1 
2         38               Level             2')
Run Code Online (Sandbox Code Playgroud)

具有给定列顺序的修改样本数据集(出现顺序或字母顺序除外):

x3 <- readr::read_table(
"ID        Answer        ColumnName        Col
1         Anduin        First Name        3
1         Wrynn         Surname           1
1         Alliance      Faction           2
2         Sylvanas      First Name        3
2         Windrunner    Surname           1
2         Horde         Faction           2")
Run Code Online (Sandbox Code Playgroud)


Rui*_*das 0

我没有看到dcast允许指定列的最终顺序的参数,但始终可以对结果进行子集化。

fun_dcast <- function(DF, formula = ID ~ ColumnName, value.var = "Answer"){
  reshape2::dcast(DF, formula, value.var = value.var)[c(1, 1 + unique(DF[["Col"]]))]
}

fun_dcast(x1)
#  ID  Faction First Name    Surname
#1  1 Alliance     Anduin      Wrynn
#2  2    Horde   Sylvanas Windrunner

fun_dcast(x2)
#  ID Level         Quest
#1  1    90 The Kirin Tor
#2  2    38      Emissary
Run Code Online (Sandbox Code Playgroud)

数据。

x1 <- read.table(text = "
ID        Answer        ColumnName        Col
1         Anduin        'First Name'        1
1         Wrynn         Surname           2
1         Alliance      Faction           3
2         Sylvanas      'First Name'        1
2         Windrunner    Surname           2
2         Horde         Faction           3
", header = TRUE)


x2 <- read.table(text = "
ID        Answer        ColumnName        Col
1         'The Kirin Tor' Quest             1
1         90            Level             2
2         Emissary      Quest             1
2         38            Level             2
", header = TRUE)
Run Code Online (Sandbox Code Playgroud)