一次变异/替换

时间:2014-08-21 08:35:01

标签: r

MAJOR EDIT

考虑一个简单的数据框:

    df = data.frame(obs.no = 1:10, conc = rnorm(10))
    discard.obs.no = 1:5

我想要这个:

    df[df$obs.no %in% discard.obs.no,"conc"] = df[df$obs.no %in% discard.obs.no,"conc"]

使用类似的辅助函数完成:

    change(df[df$obs.no %in% discard.obs.no,"conc"], function(x) 2^x)

基本上我想避免在赋值运算符的RHS上重新输入LHS。为什么?因为复杂的过滤使整个事情变得笨拙。

如示例所示,该函数应仅更改已过滤的数据,而不是返回子集。它也应该在后台发生,即不重新分配给原始data.frame。

Mutate / transform / within等不起作用,因为它们打印到控制台,需要重新分配。 Assign不会将data.frames的一部分作为参数。整件事是一个虚荣的项目,但我确信那里有一个可以做到的人(:

BONUS:尝试编写一个可以进一步缩短它的解析器:

    change(2^df[df$obs.no %in% 1:5,"conc"])

即。找出哪个部分是要重新分配的对象 - 左边/右边的$或左边的[以及[]之间。

2 个答案:

答案 0 :(得分:2)

基地R不支持您要求的内容。或者更确切地说,它可能是您要求传递引用语义,这违反了R的核心"功能"编程风格。实现它需要一些hackery。

因此,您可以使用 data.table

来实现这一目标
set.seed(1)
library("data.table")
dt <- data.table(obs.no = 1:10, conc = rnorm(10))
dt[obs.no %in% discard.obs.no, conc2 := 2^conc]
dt
    obs.no       conc     conc2
 1:      1 -0.6264538 0.6477667
 2:      2  0.1836433 1.1357484
 3:      3 -0.8356286 0.5603388
 4:      4  1.5952808 3.0215332
 5:      5  0.3295078 1.2565846
 6:      6 -0.8204684        NA
 7:      7  0.4874291        NA
 8:      8  0.7383247        NA
 9:      9  0.5757814        NA
10:     10 -0.3053884        NA

我在这里显示conc2 := 2^conc,例如,您也可以使用类似的符号将其存储回conc变量本身。

答案 1 :(得分:0)

不完全确定你的目标,但dplyr包将做你想做的事(我想)。在下面的示例中,不需要select命令,但您在问题中提到了corr列,因此我认为这可能有助于您了解可以执行的操作。

# Load the dplyr package
library(dplyr)
# create an index of values to discard
discard.obs.no <- 1:5
df <- data.frame(conc = rnorm(10), obs.no = 1:10)
modified <- df %>%
    # Select the columns you want to use by names
    select(obs.no, conc) %>%
    # use a logical statement to subset the rows you want to use
    filter(!(obs.no %in% discard.obs.no)) %>%
    # Provide a function to manipulate the data
    mutate(changed_conc = 2^conc)