【问题标题】:dcast summarise on single columndcast 在单列上汇总
【发布时间】:2017-03-22 23:06:58
【问题描述】:

我想转换我的数据,以便使用 dcast 获得平均存活率,但似乎不可能:

数据

PassengerId Survived    Pclass  Name    Sex Age SibSp   Parch   Ticket  Fare    Cabin   Embarked
1   0   3   Braund, Mr. Owen Harris male    22  1   0   A/5 21171   7.25        S
2   1   1   Cumings, Mrs. John Bradley (Florence Briggs Thayer) female  38  1   0   PC 17599    71.2833 C85 C
3   1   3   Heikkinen, Miss. Laina  female  26  0   0   STON/O2. 3101282    7.925       S

示例数据代码:

df <- structure(list(PassengerId = 1:6, Survived = structure(c(1L, 
                                                                  2L, 2L, 2L, 1L, 1L), .Label = c("0", "1"), class = "factor"), 
                        Pclass = c(3L, 1L, 3L, 1L, 3L, 3L), Name = c("Braund, Mr. Owen Harris", 
                                                                     "Cumings, Mrs. John Bradley (Florence Briggs Thayer)", "Heikkinen, Miss. Laina", 
                                                                     "Futrelle, Mrs. Jacques Heath (Lily May Peel)", "Allen, Mr. William Henry", 
                                                                     "Moran, Mr. James"), Sex = c("male", "female", "female", 
                                                                                                  "female", "male", "male"), Age = c(22, 38, 26, 35, 35, NA
                                                                                                  ), SibSp = c(1L, 1L, 0L, 1L, 0L, 0L), Parch = c(0L, 0L, 0L, 
                                                                                                                                                  0L, 0L, 0L), Ticket = c("A/5 21171", "PC 17599", "STON/O2. 3101282", 
                                                                                                                                                                          "113803", "373450", "330877"), Fare = c(7.25, 71.2833, 7.925, 
                                                                                                                                                                                                                  53.1, 8.05, 8.4583), Cabin = c("", "C85", "", "C123", "", 
                                                                                                                                                                                                                                                 ""), Embarked = c("S", "C", "S", "S", "S", "Q")), .Names = c("PassengerId", 
                                                                                                                                                                                                                                                                                                              "Survived", "Pclass", "Name", "Sex", "Age", "SibSp", "Parch", 
                                                                                                                                                                                                                                                                                                              "Ticket", "Fare", "Cabin", "Embarked"), row.names = c(NA, 6L), class = "data.frame")

目前的功能:

reshape2::dcast(titanic, Sex ~ ., mean)

期望的输出:

Row Label  Average of Survived 
Male       3.14156  
Female     3.14156

目前,它返回此错误:

     Sex  .
1 female NA
2   male NA
Warning messages:
1: In mean.default(.value[0], ...) :
  argument is not numeric or logical: returning NA

我认为这可能与 reshape 中的 cast 函数有关,但这可能与 reshape2 有关吗?

【问题讨论】:

  • 在您的幸存列中,1 表示幸存,0 表示未幸存吗?
  • 是的,没错。我会假设你应该能够轻松地做到这一点,但也许它在 data.table 中,而不是 reshape2
  • 能否提供更多数据行(尤其是《性与幸存者》)?我认为其他列对您的计算并不重要。
  • dcast 通常用于旋转到多个列(也许总是?)。如果您只需要一列,请使用DT[, mean(Survived == "1"), by=Sex] 或类似名称。如果您使用的是 reshape2 而不是 data.table,那么还有来自 base... 或 tapplyaggregate
  • @Frank 是的,我想进一步澄清您是否应该为此使用 dcast,因为使用 pandas 数据透视表很容易做到,而且看起来您可以使用(从重塑纸):演员(ffm,治疗〜.,长度)治疗(全部)1 2 3 1 1159 2 1157 3 1155

标签: r data.table dplyr reshape2


【解决方案1】:

因此,您确实可以为此使用 dcast,但 Survived 是一个因素,它会引发错误,您需要定义要用作计算值的列。结果显示列顺序也无关紧要,这令人惊讶。

df$Survived <- as.numeric(as.character(df$Survived))
reshape2::dcast(df, Sex~., mean, value.var = "Survived")
#     Sex .
#1 female 1
#2   male 0

【讨论】:

  • 当我使用给定的dput() 数据运行此代码时,它会返回 3 个警告:argument is not numeric or logical: returning NA。结果显示NA 代表女性和男性。这看起来不像我的预期结果。
  • dput 代码生成 Survived 作为因子变量。需要使用此代码将其转换为数字,并且应该可以正常工作: df$Survived
  • @petergensler 根据您的回答,这意味着您的预期结果是女性为 1,男性为 0。如果是,则它与您的问题中所需的输出不同,即男性和女性的 3.14156
  • 这些数字只是占位符,而不是预期的结果。
【解决方案2】:

dplyr试试怎么样?

library(dplyr)
output <-  df  %>% 
  dplyr::mutate(Survived = as.numeric(as.character(Survived))) %>%  
  dplyr::select(Sex, Survived) %>% 
  dplyr::group_by(Sex) %>% 
  dplyr::summarise(average_of_survived = mean(Survived))
output
## A tibble: 2 × 2
#     Sex average_of_survived
#   <chr>               <dbl>
#1 female                   1
#2   male                   0

【讨论】:

  • dplyr 绝对是一个选择,我很好奇是否可以使用 reshape2 完成这么简单的事情。过去,您似乎可以使用 cast 功能。
  • 当我使用给定的dput() 数据运行此代码时,它会返回一个警告:argument is not numeric or logical: returning NA。而output 只有一行:1 female NA。所以它看起来不像我预期的结果。
  • @UweBlock 感谢 Uwe。请检查更新的答案。
【解决方案3】:

这可以通过reshape2(或data.table)包中的dcast() 来完成,如OP's own answer 所示。

如果没有dcast(),您也可以直接使用data.table 进行聚合:

library(data.table)
setDT(df)[, Survived := as.numeric(as.character(Survived))][, mean(Survived), by = Sex]
#      Sex V1
#1:   male  0
#2: female  1

df 被 Q 中的dput() 使用。链接用于形成“单线”。

上面的一个更简洁的版本是

setDT(df)[, mean(as.numeric(as.character(Survived))), by = Sex]

【讨论】:

  • 非常感谢您的解决方案!很高兴知道这可以通过 data.table 实现
  • @petergensler,很高兴您发现该解决方案很有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 2012-01-30
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多