我一直在使用Stata,循环很容易在那里执行。但是,在R中,我在遍历变量时遇到了一些错误。我在这里尝试了一些代码,它不起作用。基本上,我试图通过记录值来清理数据。在记录负值之前,我必须先将其转换为正值。
我打算在数据框上遍历多个公司统计信息,但是这样做却遇到了错误。
varlist <- c("revenue", "profit", "cost")`
for (v in varlist) {
data$log_v <- log(abs(ifelse(data$v>1, data$v, NA)))
data$log_v <- ifelse(data$v<0, data$log_v*-1,data$log_v)
}
$ <-。data.frame( tmp ,“ log_v”,value = numeric(0))错误:替换有0行,数据有9
答案 0 :(得分:2)
看起来您可能假设data $ log_v已被读取为data $ log_profit,但是R将拥有自己的所有权并将其全部读为“ log_v” 3次。这个示例可能不完全是您要尝试做的所有事情,但可能会对您有所帮助。它获取变量列表,并通过其字符串名称引用它们。
df <- data.frame(x = rnorm(15), y = rnorm(15))
vars <- c("x", "y")
for (v in vars) {
df[paste0("log_", v)] <- log(abs(df[v]))
}
data.table中的内容大致相同。
library(data.table)
dt <- data.table(x = rnorm(15), y = rnorm(15))
dt[, `:=`(log_x = log(abs(x)), log_y = log(abs(y)))]
答案 1 :(得分:1)
以下是造成您困惑的原因的解释:
data.frame
是列表的一种特殊类型,它的元素是长度相同的矢量–列。通常,您使用[[
函数访问列表的元素,例如df[["revenue"]]
。除了"revenue"
,还可以使用变量,例如df[[varlist[1]]]
。到目前为止,一切都很好。
但是,列表具有便捷运算符$
,该运算符使您可以以较少的输入方式访问元素:df$revenue
。不幸的是,您不能以这种方式使用变量:这是设计使然。由于您不必在$
中使用引号,因此运算符无法知道您是将revenue
表示为元素的文字名称还是将revenue
用作包含以下内容的文字名称的变量元素。
因此,如果要使用变量,则需要使用[[
函数,而不要使用$
。由于程序员讨厌打字并且希望使代码尽可能简洁,因此已经发明了各种绕过打字的方式,例如data.tables
和tidyverse
(我在这里有点夸张)。
此外,这是一个整洁的解决方案。
library(tidyverse)
varlist <- c("revenue", "profit", "cost")
df <- data.frame(revenue=rnorm(100), profit=rnorm(100), cost=rnorm(100))
df <- df %>% mutate_at(varlist, list(log10 = ~ log10(abs(.))))
说明:
mutate_all
将log10(abs(.))
应用于每一列。点.
是一个临时变量,用于保存每个列的列值。mutate_all
将替换现有变量。但是,如果您提供命名列表(~ log10(abs(.))
而不是提供功能(list(log10 = ~ log10(abs(.)))
),它将使用log10
作为列名的后缀来添加新列。看到了吗?根本没有(显而易见的)循环!