gpt4 book ai didi

r - 取决于 R 中多个条件的混合数据帧的总和

转载 作者:行者123 更新时间:2023-12-04 11:04:22 28 4
gpt4 key购买 nike

这是对我之前的 question 的更复杂的后续操作.答案是使用矩阵,但这不适用于具有不同模式值的数据框。

我想将不同大小的数据框与字符和整数列组合在一起,并根据多个条件计算它们的总和。

状况

  • 仅针对具有匹配“名称”值的那些行计算总和
  • 仅针对匹配的列名计算总和
  • 如果 df4 中的单元格不是 0 也不是 NA,总和应该是 df3 + df4
  • 否则总和应该是 df1 + df2 + df3

  • 例子
    > df1 <- data.frame(Name=c("Joe","Ann","Lee","Dan"), "1"=c(0,1,5,2), "2"=c(3,1,0,0), "3"=c(2,0,2,2), "4"=c(2,1,3,4))
    > df1
    Name X1 X2 X3 X4
    1 Joe 0 3 2 2
    2 Ann 1 1 0 1
    3 Lee 5 0 2 3
    4 Dan 2 0 2 4

    > df2 <- data.frame(Name=c("Joe","Ann","Ken"), "1"=c(3,4,1), "2"=c(2,3,0), "3"=c(2,4,3))
    > df2
    Name X1 X2 X3
    1 Joe 3 2 2
    2 Ann 4 3 4
    3 Ken 1 0 3

    > df3 <- data.frame(Name=c("Lee","Ben"), "1"=c(1,3), "2"=c(3,4), "3"=c(4,3))
    > df3
    Name X1 X2 X3
    1 Lee 1 3 4
    2 Ben 3 4 3

    条件取决于此框架:
    > df4 <- data.frame(Name=c("Lee","Ann","Dan"), "1"=c(6,0,NA), "2"=c(0,0,4), "3"=c(0,NA,0))
    > df4
    Name X1 X2 X3
    1 Lee 6 0 0
    2 Ann 0 0 NA
    3 Dan NA 4 0

    对于上述示例,这是预期结果(* 值取决于 df4):
    > dfsum
    Name X1 X2 X3 X4
    1 Joe 3 5 4 2
    2 Ann 5 4 4 1
    3 Lee 7* 3 6 3
    4 Dan 2 4* 2 4
    5 Ken 1 0 3 NA
    6 Ben 3 4 3 NA

    可能的步骤?

    首先将df1、df2、df3、df4展开为5列6行,用NA填充缺失数据。

    然后对于每个数据帧:
  • 按“名称”对行进行排序
  • 将“名称”列与“X1”...“X4”分开
  • 将“X1”...“X4”列转换为矩阵
  • 计算矩阵的总和,就像我另一个问题的答案 一样但是 附加条件 1
  • 将结果矩阵转换为数据框
  • cbind“名称”列与结果数据框

  • 这如何在 R 中完成?

    解决方案

    @Ricardo Saporta 的解决方案几乎没有变化:

    添加 , padValue=NA)在四个 addCols() 中。

    如回答 here ,将 sumD3D4 和 dtsum 的定义替换为:
    plus <- function(x) {
    if(all(is.na(x))){
    c(x[0],NA)} else {
    sum(x,na.rm = TRUE)}
    }

    sumD3D4 <- setkey(rbind(dt3, dt4)[,lapply(.SD, plus), by = Name], "Name")
    dtsum <- setkey(rbind(dt1, dt2, dt3)[, lapply(.SD, plus), by=Name], "Name")

    最佳答案

    如果你使用 data.table 而不是 data.frame,你可以使用它的 by=xxxx功能,按名称添加。
    下面的代码应该为您提供预期的结果。

    请注意,我正在用额外的空列填充 data.tables。然而,我们计算 condTrue在此之前。

    library(data.table)
    dt1 <- data.table(df1)
    dt2 <- data.table(df2)
    dt3 <- data.table(df3)
    dt4 <- data.table(df4)

    # make sure all dt's have the same columns
    #-----------------------------------------#

    # identify which dt4 satisfy the condition
    condTrue <- as.data.table(which(!(is.na(dt4) | dt4==0), arr.ind=TRUE))

    # ignore column "Name" from dt4
    condTrue <- condTrue[col>1]

    # convert from (row, col) index to ("Name", columnName)
    condTrue <- data.table(Name=dt4[condTrue$row, Name], colm=names(dt4)[condTrue$col], key="Name")


    # First make a list of all the unique column names
    allColumnNames <- unique(c(names(dt1), names(dt2), names(dt3), names(dt4)))

    # add columns as necessary, using addCols (definted below)
    addCols(dt1, allColumnNames)
    addCols(dt2, allColumnNames)
    addCols(dt3, allColumnNames)
    addCols(dt4, allColumnNames)


    sumD3D4 <- setkey(rbind(dt3, dt4)[, lapply(.SD, sum), by=Name], "Name")
    dtsum <- setkey(rbind(dt1, dt2, dt3)[, lapply(.SD, sum), by=Name], "Name")

    for (Nam in condTrue$Name) {
    colsRepl <- condTrue[.(Nam)]$colm
    valsRepl <- unlist(sumD3D4[.(Nam), c(colsRepl), with=FALSE])
    dtsum[.(Nam), c(colsRepl) := as.list(valsRepl)]
    }

    dtsum
    # Name 1 2 3 4
    # 1: Ann 5 4 4 1
    # 2: Ben 3 4 3 0
    # 3: Dan 2 4 2 4
    # 4: Joe 3 5 4 2
    # 5: Ken 1 0 3 0
    # 6: Lee 7 3 6 3
    addCols <- function(x, cols, padValue=0)  {
    # adds to x any columns that are in cols but not in x
    # Returns TRUE if columns were added
    # FALSE if no columns added
    colsMissing <- setdiff(cols, names(x))

    # grab the actual DT name that was passed to function
    dtName <- as.character(match.call()[2])

    if (length(colsMissing)) {
    get(dtName, envir=parent.frame(1))[, c(colsMissing) := padValue]
    return(TRUE)
    }

    return(FALSE)
    }

    关于r - 取决于 R 中多个条件的混合数据帧的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15044342/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com