R within() 操作顺序和逻辑

R within() order of operation and logic

我试图了解 R 中的 within() 函数如何运行 "works." 例如,在下面的代码中,我尝试根据条件创建一个名为 "FEELS" 的新变量。 within() 函数的前两个用法不起作用。 within() 函数的第三次使用有效,但我不确定我是否理解 "why" 它有效的逻辑。感谢任何帮助。

DF <- data.frame(DATE = seq(as.Date("2015-01-01"), as.Date("2015-12-31"), "month"), TEMP = c(30, 40, 50, 60, 70, 80, 90, 100, 90, 80, 70, 60))

DF <- within(DF, {
  FEELS[30 <= TEMP & TEMP <=  50] <- "Cold"
  FEELS[60 <= TEMP & TEMP <=  70] <- "Good"
  FEELS[80 <= TEMP & TEMP <= 100] <- "Hot"
})

DF <- within(DF, {
  FEELS                           <- "Cold"
  FEELS[60 <= TEMP & TEMP <=  70] <- "Good"
  FEELS[80 <= TEMP & TEMP <= 100] <- "Hot"
})

DF

DF <- within(DF, {
  FEELS                           <- NA
  FEELS[60 <= TEMP & TEMP <=  70] <- "Good"
  FEELS[80 <= TEMP & TEMP <= 100] <- "Hot"
  FEELS[is.na(FEELS)]             <- "Cold"
})

DF

让我们一一分解。

1. 这只会导致一条错误消息:

Error in FEELS[30 <= TEMP & TEMP <= 50] <- "Cold" : object 'FEELS' not found

这很有道理。您尚未定义 FEELS,因此对其进行子集化会导致错误。

2.这个很有意思,在'within'以外的地方看会更清楚

FEELS <- "cold"
tf <- 60 <= DF$TEMP & DF$TEMP <=  70
tf

[1] FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE

FEELS[tf] <- "Good"
FEELS

 [1] "cold" NA     NA     "Good" "Good" NA     NA     NA     NA     NA     "Good"
[12] "Good"

R 以包含 "cold" 的长度为 1 的向量开始,但是您的子集化强制它扩展并将 "Good" 放置在它是 TRUE 的所有元素中。 R 对 FALSE 的所有内容都没有任何值,因此将 NA 放在那里。

3. 最后一个很简单。您从一个 NA 向量开始,它的扩展方式与 2 中的向量相同。然后用 "cold".

替换所有剩余的 NA

当您在 within(DF, {...}) 中创建对象时,它不会自动具有与 DF 的列相同的长度。而是在{...}末尾"recycled"填写

within(data.frame(A=1:6), { B = 1; C = 1:2 })
#   A C B
# 1 1 1 1
# 2 2 2 1
# 3 3 1 1
# 4 4 2 1
# 5 5 1 1
# 6 6 2 1

如果在 {...} 结束之前,您想要修改一个对象,就像它是一个完整的列一样,它必须具有正确的长度:

within(data.frame(A=1:6), {
  D = 1 
  D[ A < 3 ] = 0
  D2 = rep(1, length(A))
  D2[A < 3 ] = 0
})

#   A D2  D
# 1 1  0  0
# 2 2  0  0
# 3 3  1 NA
# 4 4  1 NA
# 5 5  1 NA
# 6 6  1 NA

要理解为什么 D2 给出了预期的输出而 D 没有,请尝试按步骤检查对象,按照 @sebastian-c 的建议使用 browser() 或按照以下步骤操作如他的回答所示。

在 OP 的情况下,使用 rep 进行初始化然后进行多次替换是一种选择。另一种方法是使用 cut,它是为将标签分配给有序数据的间隔而设计的。