【问题标题】:R Summarize Collapsed Data.TableR总结折叠的Data.Table
【发布时间】:2020-05-05 10:29:29
【问题描述】:

我有这样的数据

data <- data.table(
 "School" = c(1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 
              1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0),
 "Grade"  = c(0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 
              0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0),
 "CAT"    = c(1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 
              0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1),
 "FOX"    = c(1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 
              1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0),
 "DOG"    = c(0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 
              0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1)
)

并希望实现这样的新数据表:

dataWANT <- data.frame(
  "VARIABLE" = c('CAT', 'CAT', 'CAT', 'FOX', 'FOX', 'FOX', 'DOG', 'DOG', 'DOG'),
  "SCHOOL" = c(1, 1, 0, 1, 1, 0, 1, 1, 0),
  "GRADE"  = c(0, 1, 1, 0, 1, 1, 0, 1, 1),
  "MEAN"   = c(NA)
)

dataWANT 取 CAT 和 FOX 和 DOG 的平均值,通过 SCHOOL、GRADE 和 SCHOOL X GRADE 当它们等于 1 时。

我知道如何一次完成一项,但这不利于处理大数据。

data[, CAT1 := mean(CAT), by = list(SCHOOL)]
data[, FOX1 := mean(FOX), by = list(GRADE)]
data[, DOG1 := mean(DOG), by = list(SCHOOL, GRADE)]
    
data$CAT2 = unique(data[SCHOOL == 1, CAT1])
data$FOX2 = unique(data[GRADE == 1, FOX1])
data$DOG2 = unique(data[SCHOOL == 1 & GRADE == 1, DOG1])

请只使用这个:

data <-  data.table(
  "SCHOOL" = c(1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 
               1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0),
  "GRADE"  = c(0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 
               0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0),       
  "CAT"    = c(1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0,
               0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1),
  "FOX"    = c(1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1,
               1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0),
  "DOG"    = c(0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0,
               0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1)
)
    
    
data[, CAT1 := mean(CAT), by = list(SCHOOL)]
data[, CAT2 := mean(CAT), by = list(GRADE)]
data[, CAT3 := mean(CAT), by = list(SCHOOL, GRADE)]

data[, FOX1 := mean(FOX), by = list(SCHOOL)]
data[, FOX2 := mean(FOX), by = list(GRADE)]
data[, FOX3 := mean(FOX), by = list(SCHOOL, GRADE)]

data[, DOG1 := mean(DOG), by = list(SCHOOL)]
data[, DOG2 := mean(DOG), by = list(GRADE)]
data[, DOG3 := mean(DOG), by = list(SCHOOL, GRADE)]


dataWANT <- data.frame(
  "VARIABLE" = c('CAT', 'CAT', 'CAT', 'FOX', 'FOX', 'FOX', 'DOG', 'DOG', 'DOG'),
  "TYPE"     = c(1, 2, 3, 1, 2, 3, 1, 2, 3),
  "MEAN"     = c(0.48, 0.44, 0.428, 0.6, 0.611, 0.6428, 0.52, 0.61, 0.6428)
)

其中:
当MEAN 由SCHOOL 估计时,TYPE 等于1,
当MEAN 由GRADE 估计时,TYPE 等于2,
@987654339当MEAN 由SCHOOL 和GRADE 估计时,@ 等于3

【问题讨论】:

  • 你需要melt(data, id.var = c('School', 'Grade'))[, .(MEAN = mean(value == 1)) , .(School, Grade, variable)]
  • @akrun 谢谢,请在“请仅使用此:”下使用此数据,谢谢,它包含完全可重复的所需输出
  • @akrun 谢谢,是的——我希望自动创建此代码。我展示了我学会了如何做到这一点,但它不是很有效,因为我有 100 多个变量,所以自动化的方式来做到这一点是理想的,我可以提供一个 colnames 向量。最终目标是从数据中获得 dataWANT
  • @akrun 我很抱歉我没有澄清这一点。我更新了帖子。
  • 你能检查一下我的解决方案吗

标签: r data.table summary


【解决方案1】:

我们可以在创建list 之后使用rbindlist,方法是在melting 数据集之后获取MEAN(如另一篇文章中所述)

library(data.table)
cols <- c('CAT', 'FOX', 'DOG')
data1 <- melt(data, measure.vars = cols)
list_cols <- list('SCHOOL', 'GRADE', c('SCHOOL', 'GRADE'))
lst1 <- lapply(list_cols, function(x)  
       data1[, .(MEAN = mean(value, na.rm = TRUE)), c(x, 'variable')])
rbindlist(lapply(lst1, function(x)  {
     nm1 <- setdiff(names(x), c('variable', 'MEAN'))
     x[Reduce(`&`, lapply(mget(nm1), as.logical)),
     .(VARIABLE = variable, MEAN)]}), idcol = 'TYPE')[order(VARIABLE)]
#   TYPE VARIABLE      MEAN
#1:    1      CAT 0.4800000
#2:    2      CAT 0.4444444
#3:    3      CAT 0.4285714
#4:    1      FOX 0.6000000
#5:    2      FOX 0.5555556
#6:    3      FOX 0.6428571
#7:    1      DOG 0.5200000
#8:    2      DOG 0.6111111
#9:    3      DOG 0.6428571

【讨论】:

  • 另一个完美的解决方案非常感谢。如果您有兴趣,我今天还有一个问题,stackoverflow.com/questions/61623465/…
  • @bvowe 谢谢,在那个问题中你有比例值,chisq 测试比较计数
【解决方案2】:

你的意思是得到这样的东西吗?

library(data.table)

melt(data, measure.vars = c('CAT', 'FOX', 'DOG'))[, 
        .(MEAN = mean(value, na.rm = TRUE)), .(School, Grade, variable)]

要按不同的列分组,我们可以这样做:

cols <- c('CAT', 'FOX', 'DOG')
data1 <- melt(data, measure.vars = cols)
list_cols <- list('School', 'Grade', c('School', 'Grade'))

lapply(list_cols, function(x)  
         data1[, .(MEAN = mean(value, na.rm = TRUE)), c(x, 'variable')])

【讨论】:

  • 是的,我想就是这样。我的问题是,如果我想按学校、然后按年级、然后按两者怎么办?另外如何输入VAR名称的向量而不是在melt函数中列出?
  • @bvowe 更新了答案,这是你的意思吗?
  • 是的,这是完美的,然后将不同的列表一起提取并放入数据框中,我尝试了这个 x=data1[[1]][School == 1] y=data1[[2]] [Grade == 1] z=data1[[3]][School == 1 & Grade == 1] Z = cbind(x,y,z) 但我怎样才能让它看起来像示例中的 dataWANT?跨度>
  • 我不确定我是否理解正确。您只是想将lapply 中的行绑定在一起吗? dplyr::bind_rows(lapply(list_cols, function(x) data1[, .(MEAN = mean(value, na.rm = TRUE)), c(x, 'variable')])) ?
  • 非常感谢您,我用所需的确切数据输出更新了问题,如果可以,请看看,如果这有助于澄清
【解决方案3】:

您可以先使用lapply(.SD,...) 子集并计算您的均值,然后将其融合到您的输出中:

melt(data[School != 0 | Grade != 0, lapply(.SD, mean), by = .(School, Grade)], id.vars = c("School", "Grade"))

添加这个之后也会添加 TYPE 变量

...][, TYPE := School + (2*Grade)]

将所有内容放在一起并整理一下,它与您想要的输出相匹配

dataWANT <- melt(data[School != 0 | Grade != 0, lapply(.SD, mean), by = .(School, Grade)], id.vars = c("School", "Grade"))[, TYPE := School + (2*Grade)][order(variable, TYPE), .("VARIABLE" = variable, TYPE, "MEAN" = value)] 

【讨论】:

    猜你喜欢
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 2021-06-11
    • 2015-09-25
    • 2014-08-04
    • 2017-01-30
    相关资源
    最近更新 更多