【问题标题】:Choose dataframe variables by name and multiply with a vector elementwise按名称选择数据框变量并按元素乘以向量
【发布时间】:2021-12-15 20:59:21
【问题描述】:

我有一个数据框和一个向量如下:

my_df <- as.data.frame(
list(year = c(2001, 2001, 2001, 2001, 2001, 2001), month = c(1, 
2, 3, 4, 5, 6), Pdt_d0 = c(0.379045935402736, 0.377328817455841, 
0.341158889847019, 0.36761990427443, 0.372442657083218, 0.382702189949558
), Pdt_d1 = c(0.146034519173855, 0.166289573095497, 0.197787188740911, 
0.137071647982617, 0.162103042313547, 0.168566518193772), Pdt_d2 = c(0.126975939811326, 
0.107708783271871, 0.14096203677089, 0.142228236885706, 0.115542396064519, 
0.106935751726809), Pdt_tot = c(2846715, 2897849.5, 2935406.25, 
2850649, 2840313.75, 3087993.5))
)

my_vec <- 1:3

我想将Pdt_d0:Pdt_d2my_vec 中的相应元素相乘,同时保持其他列不变。我可以使用dplyr::select(my_df, num_range("Pdt_d", 0:2)) %&gt;% mapply(``*``, ., my_vec) 获得所需的乘法,但在此过程中我丢失了year, month, Pdt_tot 列。我尝试使用dplyr::select(my_df, num_range("Pdt_d", 0:2)) &lt;- dplyr::select(my_df, num_range("Pdt_d", 0:2)) %&gt;% mapply(``*``, ., my_vec) 实现我的目标,它返回错误'select&lt;-' is not an exported object。有什么我没有看到的明显技巧吗?

我不认为我的问题是重复的;我已经在herehere 中看到了答案,但是这两个问题都不允许我按名称选择变量

【问题讨论】:

    标签: r dataframe vector subset


    【解决方案1】:

    您可以在整洁的世界之外使用您尝试过的右侧Map/mapply 逻辑覆盖的左侧:

    vars <- paste0("Pdt_d", 0:2)
    my_df[vars] <- Map(`*`, my_df[vars], my_vec)
    my_df
    
    #  year month    Pdt_d0    Pdt_d1    Pdt_d2 Pdt_tot
    #1 2001     1 0.3790459 0.2920690 0.3809278 2846715
    #2 2001     2 0.3773288 0.3325791 0.3231263 2897850
    #3 2001     3 0.3411589 0.3955744 0.4228861 2935406
    #4 2001     4 0.3676199 0.2741433 0.4266847 2850649
    #5 2001     5 0.3724427 0.3242061 0.3466272 2840314
    #6 2001     6 0.3827022 0.3371330 0.3208073 3087994
    

    这是有效的,因为[&lt;- 在 R 中作为一个函数存在,用于通过方括号分配给左侧选择,例如 my_df[]
    返回的错误是因为代码左侧有一个select() 函数,而没有'select&lt;-' 函数。即,您不能分配给select()-ion,因为它没有设置为那样工作。整洁的函数通常期望像my_df %&gt;% select() %&gt;% etc 一样通过管道传递而不覆盖原始输入。

    【讨论】:

    • 作为后续:当my_df 是数据框列表时,是否可以使用[&lt;-?当我针对my_df 是数据帧列表my_df[vars] 的情况尝试上述逻辑时,我得到NULL 值列表
    • @ptr64 - 是的,你必须遍历列表然后替换整个列表 - my_df[] &lt;- lapply(my_df, \(x) { x[vars] &lt;- Map(`*`, x[vars], my_vec); x})
    【解决方案2】:

    我不认为你想把这件事弄得一团糟,但它确实有效。

    library(dplyr)
    library(tidyr)
    
    my_df %>%
      gather(variable, value, -year,-month,-Pdt_tot) %>%
      group_by(year, month, Pdt_tot) %>%
      mutate(value = value * my_vector) %>%
      spread(variable,value)
    
       year month  Pdt_tot Pdt_d0 Pdt_d1 Pdt_d2
      <dbl> <dbl>    <dbl>  <dbl>  <dbl>  <dbl>
    1  2001     1 2846715   0.379  0.292  0.381
    2  2001     2 2897850.  0.377  0.333  0.323
    3  2001     3 2935406.  0.341  0.396  0.423
    4  2001     4 2850649   0.368  0.274  0.427
    5  2001     5 2840314.  0.372  0.324  0.347
    6  2001     6 3087994.  0.383  0.337  0.321
    

    没有指定yearmonthPdt_tot是,

    my_df %>%
      gather(variable, value, - !num_range("Pdt_d", 0:2)) %>%
      group_by(across(c(-variable, -value))) %>%
      mutate(value = value * my_vector) %>%
      spread(variable, value)
    
       year month  Pdt_tot Pdt_d0 Pdt_d1 Pdt_d2
      <dbl> <dbl>    <dbl>  <dbl>  <dbl>  <dbl>
    1  2001     1 2846715   0.379  0.292  0.381
    2  2001     2 2897850.  0.377  0.333  0.323
    3  2001     3 2935406.  0.341  0.396  0.423
    4  2001     4 2850649   0.368  0.274  0.427
    5  2001     5 2840314.  0.372  0.324  0.347
    6  2001     6 3087994.  0.383  0.337  0.321
    

    【讨论】:

      猜你喜欢
      • 2014-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-16
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      相关资源
      最近更新 更多