【问题标题】:Duplicate columns with programatic names具有程序名称的重复列
【发布时间】:2019-08-02 08:53:25
【问题描述】:

我有需要分成几个月的年度数据。操作非常简单,只需将月份的年度数据平均分配即可。

我的第一步是复制年度列 12 次,并使用适当的列名称(月份)。下一步是将每列除以 12。

我被困在第一步,因为我能够创建月份列,但只填充了第一个,其余的只是 NAs

使用 Iris 数据集查看下面的一些代码

months <- paste(2019,seq(1,12,1), sep = "-")
map_df(months, ~
             iris %>% mutate(!!.x := Sepal.Length))
   Sepal.Length Sepal.Width Petal.Length Petal.Width    Species 2019-1 2019-2 2019-3 2019-4 2019-5 2019-6 2019-7 2019-8 2019-9 2019-10 2019-11 2019-12
1           5.1         3.5          1.4         0.2     setosa    5.1     NA     NA     NA     NA     NA     NA     NA     NA      NA      NA      NA
2           4.9         3.0          1.4         0.2     setosa    4.9     NA     NA     NA     NA     NA     NA     NA     NA      NA      NA      NA
3           4.7         3.2          1.3         0.2     setosa    4.7     NA     NA     NA     NA     NA     NA     NA     NA      NA      NA      NA
4           4.6         3.1          1.5         0.2     setosa    4.6     NA     NA     NA     NA     NA     NA     NA     NA      NA      NA      NA

如您所见,2019-1 年工作正常(复制 Sepal.Length),但其余月份只是 NA。

我在这里缺少什么?

【问题讨论】:

  • data.table 中也更直接:setDT(iris)[, (months) := Sepal.Length](尽管这可能无法正常工作,因为iris 已锁定,您需要先进行复制)

标签: r dictionary dplyr purrr


【解决方案1】:

当你可以直接为多列赋值时,你真的需要这个方法吗?

df <- iris 
df[months] <- df$Sepal.Length

df[5:8]

#       Species 2019-1 2019-2 2019-3
#1       setosa    5.1    5.1    5.1
#2       setosa    4.9    4.9    4.9
#3       setosa    4.7    4.7    4.7
#4       setosa    4.6    4.6    4.6
#5       setosa    5.0    5.0    5.0
#6       setosa    5.4    5.4    5.4
#... 

【讨论】:

    【解决方案2】:

    如果您使用 for 循环来执行此操作,这应该不是什么大问题。在这里,我提供了一个使用 {data.table} 的示例。

    library(data.table)
    iris <- data.table(iris)
    
    months <- paste(2019, seq(1,12,1), sep = "-")
    
    for(i in 1:12){
    
      iris[, (months[i]) := Sepal.Length]
    
    }
    

    由于我对 {dplyr} 不太熟悉,我可以给出一个类似的等价物,但可能有更好的方法来做到这一点。

    for(i in 1:12){
    
      iris <- mutate(iris, PlaceHolder = Sepal.Length)
      names(iris) <- gsub("PlaceHolder", months[i], names(iris))
    
    }
    

    【讨论】:

      【解决方案3】:

      它们不是空的。问题是,~ 右侧的表达式返回的不是列,而是 tibble。检查您的结果有多少行:

      map_df(months, ~ iris %>% mutate(!!.x := Sepal.Length)) %>% nrow
      

      结果是1800!这是因为map_df 实际上是伪装的map_dfr,它会尝试绑定结果数据帧的行。因此,第一列将是 Sepal.Width,然后是一堆 NA;下一列——一堆 NA,然后是一堆值,然后又是一堆 NA……让我们从 iris 中只取三个日期和三行:

      months <- paste(2019,seq(1,3,1), sep = "-")
      map_df(months, ~ iris %>% slice(1:3) %>% mutate(!!.x := Sepal.Length) %>% select(!!.x))
      

      结果是

        2019-1 2019-2 2019-3
      1    5.1     NA     NA
      2    4.9     NA     NA
      3    4.7     NA     NA
      4     NA    5.1     NA
      5     NA    4.9     NA
      6     NA    4.7     NA
      7     NA     NA    5.1
      8     NA     NA    4.9
      9     NA     NA    4.7
      

      要得到你想要的,你需要使用map_dfc(按列绑定):

      map_df(months, ~ iris %>% slice(1:3) %>% mutate(!!.x := Sepal.Length) %>% select(!!.x))
      

      结果:

        2019-1 2019-2 2019-3
      1    5.1    5.1    5.1
      2    4.9    4.9    4.9
      3    4.7    4.7    4.7
      

      然而,这一切都太复杂了。你可以这样做:

      iris[,months] <- iris$Sepal.Width
      

      【讨论】:

        猜你喜欢
        • 2018-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-24
        • 2017-03-26
        • 1970-01-01
        • 1970-01-01
        • 2021-07-14
        相关资源
        最近更新 更多