【问题标题】:dplyr: Subtracting between two data tblsdplyr:两个数据表之间的减法
【发布时间】:2017-07-11 16:13:56
【问题描述】:

我有一个背景数据文件和一个实验数据文件。我需要的是从背景文件中计算colMeans,并从实验数据中减去相应的平均背景读数。

这在base r中很容易:

dataField1 <- "someField"
dataField2 <- "someField2"
ctrlMeans <- colMeans (read.csv ("ctrl.csv"))
exprData <- read.csv ("expr.csv")
exprData [, c(dataField1, dataField2)] <- exprData [, c(dataField1, dataField2)] - ctrlMeans [c(dataField1, dataField2)]

但我发现最后一步很难在 dplyr 中实现。我能得到的最好的结果如下:

ctrlMeansTbl <- read_csv ('ctrl.csv') %>% summarize_all (mean)
exprDataTbl<- read_csv('expr.csv') %>% mutate (
  dataField1 := !! quo (dataField1) - select (ctrlMeansTbl, !!quo (dataField1)),
  dataField2 := !! quo (dataField2) - select (ctrlMeansTbl, !!quo (dataField2))
)

但这会引发错误:

Error in rep_len(as.vector(e1), prod(dim(e2))) : 
  attempt to replicate non-vector

为了清楚起见,ctrlMeansTblexprDataTbl(mutate 之前)的格式如下:

> head (ctrlMeansTbl)
# A tibble: 1 x 4
  `someField1` `someField2` `someField3`    `someField4`
       <dbl>    <dbl>            <dbl>   <dbl>
1   489.7096 74.24759         547.9139 16.0828
> head (donorSingle)
# A tibble: 6 x 4
  `someField1` `someField2` `someField3`    `someField4`
       <dbl>    <dbl>            <dbl>    <dbl>
1  132123.44  1560.74        166069.17 0.619378
2   11125.93   156.95         14045.20 0.620412
3   14590.51   243.82         18132.47 0.621446
4   76014.17   839.50         95961.42 0.623514
5   91344.17  1054.85        115226.85 0.627650
6    7651.86   146.73          9528.69 0.631786

有人对此有任何想法吗?谢谢!

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    没有可复现的例子,但你可以直接减去手段:

    mtcars %>% mutate_all(funs(. - mean(.)))
    

    更通用的purrr 解决方案是:

    map2_df(mtcars, colMeans(mtcars), `-`)
    

    话虽如此,基本方式对我来说似乎完全没问题。

    【讨论】:

    • 第二个选项与@​​987654324@ 结合使用,但第一个选项没有——我收到Error in mutate_impl(.data, dots) : Evaluation error: no applicable method for 'tbl_vars' applied to an object of class "fun_list". 错误。
    • 您可以将mutate_all 替换为mutate_at,而不是第一个select。很简单。
    【解决方案2】:

    我认为您的问题是您使用select 来获取要减去的值。但是,此函数返回数据帧而不是向量。我会尝试以这种方式调整您的代码:

    ctrlMeansTbl <- read_csv ('ctrl.csv') %>% summarize_all (mean)
      exprDataTbl<- read_csv('expr.csv') %>% mutate (
      dataField1 := !! quo (dataField1) - ctrlMeansTbl$dataField1,
      dataField2 := !! quo (dataField2) - ctrlMeansTbl$dataField2
    )
    

    【讨论】:

    • 不起作用。 dataField1dataField2 是变量,所以我收到 Unknown or uninitialised column: 'dataField1'. 错误。在我使用方括号 (as.numeric(ctrlMeansTbl[1, dataField1])) 修复该问题后,我仍然收到 non-numeric argument to binary operator 错误。现在是不是一个quosure问题?
    • 能否在上面显示as.numeric(ctrlMeansTbl[1,dataField1]) 的输出以及class 的输出?
    • 你对真正数字的期望... > as.numeric(ctrlMeansTbl[1, dataField1]) [1] 489.7096 > class(as.numeric(ctrlMeansTbl[1, dataField1]) ) [1] “数字”
    • 这很奇怪...您使用的是data.table 包,对吗?您是否尝试过使用普通的dplyr 语法?我的意思是,就像dataField1 = dataField1 - ctrlMeansTbl[1,"dataField1"]。我认为这里的主要问题是语法。
    • OK,终于找到了错误的主要原因。在different thread 中提到字符串应该由sym 而不是quo 转换为quosures。
    【解决方案3】:

    将您想要mutate 的列定义为向量 (thesecols)。制作并选择ctrlMeansTbl的相关列

    library(dplyr)
    thesecols <- c("mpg","cyl")
    ctrlMeansTbl <- read_csv('ctrl.csv') %>%
                       summarize_all(mean) %>% 
                       select(thesecols)
    

    按列制作iteratorctrlMeansTbl

    library(iterators)
    bycol <- iter(ctrlMeansTbl,by="col")
    

    使用mutate_atnextElem

    exprDataTbl<- read_csv('expr.csv') %>% 
                      mutate_at(vars(thesecols), funs(. - nextElem(bycol)))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-10
      相关资源
      最近更新 更多