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
,它是为将标签分配给有序数据的间隔而设计的。
我试图了解 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
,它是为将标签分配给有序数据的间隔而设计的。