![](/img/trans.png)
[英]Adding standardized variables to a data frame using dplyr and a for loop
[英]adding new variables to a data frame using dplyr select and mutate functions in a for loop
请让我知道是否重复。 我查看了Stack并发现了类似的问题,但并没有完全回答我的问题。 我是一个初学者,所以我感谢任何人的帮助。
我试图将年度摘要变量添加到每月数据的数据框中(即,跨行求和)。 这是一个每月数据有限的示例数据框。
df <- data.frame("Jan.2012" = c(1, 4, 5, 6), "Feb.2012" = c(3, 5, 7, 9),
"Jan.2013" = c(6, 8, 9, 10), "Feb.2013" = c(7, 5, 11, 13), "Jan.2014" = c(6, 8, 9, 11),
"Feb.2014" = c(7, 3, 5, 9))
新变量将被命名为TotalYr2012,TotalYr2013等。例如,TotalYr2012 = c(4、9、12、15)等。
我试图遍历for循环(我不知道这是最佳实践)以生成这些变量。 我知道我在Assign语句中做错了一些事情,并且得到了一个错误。
for (i in 2012:2014) {
varname <- paste("TotalYr", i, sep = "")
assign(df$varname, df %>% select(contains("i")) %>%
mutate(varname = sum()))
}
谢谢你的帮助!
您可以使用tidyr::gather
和zoo::yearmon
函数来计算每年的摘要,从而避免for-loop
。
library(tidyverse)
library(zoo)
df %>% gather(Date, value) %>%
mutate(Date = as.yearmon(Date,"%b.%Y")) %>%
group_by(Year = year(Date)) %>%
summarise(Total = sum(value)) %>%
spread(Year, Total)
# # A tibble: 1 x 3
# `2012` `2013` `2014`
# * <dbl> <dbl> <dbl>
# 1 40.0 69.0 58.0
你有很多问题。
$
不适用于变量。 使用[
或[[
代替。 有关其他信息,请参见此R-FAQ 。 同样,您的缩进是混乱的,让我们保持一致:
for (i in 2012:2014) { varname <- paste("TotalYr", i, sep = "") assign(df[[varname]], df %>% select(contains("i")) %>% mutate(varname = sum())) }
不需要assign
,只需使用<-
(或=
)。 您几乎应该永远不要使用assign()
。
for (i in 2012:2014) { varname <- paste("TotalYr", i, sep = "") df[[varname]] <- df %>% select(contains("i")) %>% mutate(varname = sum())) }
"i"
是一个字符串,它的值始终是字母"i"
,就像2
的值始终是2
。 即使在contains()
你想使用已分配给该对象的值, i
(尽管该值确实需要一个字符串,也就是说,它需要类的character
):
for (i in 2012:2014) { varname <- paste("TotalYr", i, sep = "") df[[varname]] <- df %>% select(contains(as.character(i))) %>% mutate(varname = sum())) }
mutate
并select
返回数据帧,这意味着您的代码正在尝试分配一个df[[varname]]
数据帧do df[[varname]]
。 我们只想分配一个列向量,而不是整个数据帧。 因此,我们使用dplyr::pull
列向量
for (i in 2012:2014) { varname <- paste("TotalYr", i, sep = "") df[[varname]] <- df %>% select(contains(as.character(i))) %>% mutate(varname = sum())) %>% pull() }
在控制台中键入sum()
,您将获得0
。 您需要给sum()
一些东西。 让我们完全摆脱mutate
并只求出pull
ed向量的sum
,这样我们就不必担心它的名称了:
for (i in 2012:2014) { varname <- paste("TotalYr", i, sep = "") df[[varname]] <- df %>% select(contains(as.character(i))) %>% pull %>% sum }
好的,现在可以正常工作了。 但是,您要将这些新值添加到具有一堆行的旧数据框中。 新值只是单个值,因此它们被“回收”,在数据帧的每一行上重复。 让我们创建一个新的result
数据框, result
框将只包含一行:
result = list() for (i in 2012:2014) { varname <- paste("TotalYr", i, sep = "") result[[varname]] <- df %>% select(contains(as.character(i))) %>% pull %>% sum } result = as.data.frame(result) result # TotalYr2012 TotalYr2013 TotalYr2014 # 1 24 36 24
现在它可以工作了,并提供了可行的解决方案。 但是,它仍然很混乱。 for
循环通常不是必需的。 我们有更好的工具来整理数据。
# See MKR's answer. It's the way you should actually do this.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.