繁体   English   中英

使用for循环中的dplyr select和mutate函数将新变量添加到数据框

[英]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::gatherzoo::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  

你有很多问题。

  1. $不适用于变量。 使用[[[代替。 有关其他信息,请参见此R-FAQ 同样,您的缩进是混乱的,让我们保持一致:

     for (i in 2012:2014) { varname <- paste("TotalYr", i, sep = "") assign(df[[varname]], df %>% select(contains("i")) %>% mutate(varname = sum())) } 
  2. 不需要assign ,只需使用<- (或= )。 您几乎应该永远不要使用assign()

     for (i in 2012:2014) { varname <- paste("TotalYr", i, sep = "") df[[varname]] <- df %>% select(contains("i")) %>% mutate(varname = sum())) } 
  3. "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())) } 
  4. mutateselect返回数据帧,这意味着您的代码正在尝试分配一个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() } 
  5. 在控制台中键入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 } 
  6. 好的,现在可以正常工作了。 但是,您要将这些新值添加到具有一堆行的旧数据框中。 新值只是单个值,因此它们被“回收”,在数据帧的每一行上重复。 让我们创建一个新的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 
  7. 现在它可以工作了,并提供了可行的解决方案。 但是,它仍然很混乱。 for循环通常不是必需的。 我们有更好的工具来整理数据。

     # See MKR's answer. It's the way you should actually do this. 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM