【问题标题】:Manipulating by groups within data frame在数据框中按组进行操作
【发布时间】:2021-10-30 04:00:53
【问题描述】:

我有一个看起来或多或少像这样的数据框(但更长且具有更多 ObsDOY 值):

   Position              ObsDOY Offset Lin_Flux
   <chr>                  <dbl>  <dbl>    <dbl>
 1 Inter-row (unplanted)    122      1    10.7 
 2 Tree row                 122      1    10.3 
 3 Tree row                 122      1    16.2 
 4 Inter-row (planted)      122      1     9.08
 5 Inter-row (trenched)     122      1     3.57
 6 Inter-row (trenched)     122      1    12.3 
 7 Inter-row (trenched)     122      1     9.36
 8 Inter-row (trenched)     122      1     7.73
 9 Inter-row (trenched)     122      1    10.1 
10 Inter-row (trenched)     122      1     7.14
11 Inter-row (planted)      143      1     4.44

我想添加一个新列,该列是每个位置的 Lin_Flux 与与 Position = "Inter-row (trenched)" 对应且具有相同 ObsDOYLin_flux 值的平均值之间的差异@(一年中的观察日) .换句话说:

newcol &lt;- Lin_flux[ObsDOY=x] - mean(Lin_flux[ObsDOY=x AND Position = "Inter-row (trenched)"])

我会知道如何使用dplyr 包手动实现这一点,以过滤掉子集,然后使用它们,但我非常感谢关于更优雅解决方案的建议,因为我将不断添加更多观察并做不想每次都重写脚本以包含新的ObsDOY 值。

【问题讨论】:

  • 能否请您提供一个手动计算的预期输出示例,并粘贴来自dput(your_dataframe) 输出的样本数据副本。

标签: r dataframe indexing data-manipulation


【解决方案1】:

您可以使用dplyr,而无需手动对每个不同的ObsDOY 值进行子集化。为此,您只需过滤掉Position == "Inter-row (trenched)" 的那些观察值,然后为ObsDOY 的每个值创建一个新的Lin_Flux 数据集。

之后,您将数据合并回原始数据集并获取差异。

library(dplyr)
df <- tribble(
~ID, ~Position,              ~ObsDOY, ~Offset, ~Lin_Flux,
1, "Inter-row (unplanted)",    122,      1,    10.7, 
2, "Tree row",                 122,      1,    10.3, 
3, "Tree row",                 122,      1,    16.2, 
4, "Inter-row (planted)",      122,      1,     9.08,
5, "Inter-row (trenched)",     122,      1,     3.57,
6, "Inter-row (trenched)",     122,      1,    12.3, 
7, "Inter-row (trenched)",     122,      1,     9.36,
8, "Inter-row (trenched)",     122,      1,     7.73,
9, "Inter-row (trenched)",     122,      1,    10.1, 
10, "Inter-row (trenched)",     122,      1,     7.14,
11, "Inter-row (planted)",      143,      1,     4.44
)

df %>%
    filter(Position == "Inter-row (trenched)") %>%
    group_by(ObsDOY) %>%
    summarize(Lin_Flux_mean = mean(Lin_Flux)) %>%
    right_join(df, by = c("ObsDOY")) %>%
    mutate(Lin_Flux_diff = Lin_Flux - Lin_Flux_mean)

# A tibble: 11 x 7
   ObsDOY Lin_Flux_mean    ID Position              Offset Lin_Flux Lin_Flux_diff
    <dbl>         <dbl> <dbl> <chr>                  <dbl>    <dbl>         <dbl>
 1    122          8.37     1 Inter-row (unplanted)      1    10.7          2.33 
 2    122          8.37     2 Tree row                   1    10.3          1.93 
 3    122          8.37     3 Tree row                   1    16.2          7.83 
 4    122          8.37     4 Inter-row (planted)        1     9.08         0.713
 5    122          8.37     5 Inter-row (trenched)       1     3.57        -4.80 
 6    122          8.37     6 Inter-row (trenched)       1    12.3          3.93 
 7    122          8.37     7 Inter-row (trenched)       1     9.36         0.993
 8    122          8.37     8 Inter-row (trenched)       1     7.73        -0.637
 9    122          8.37     9 Inter-row (trenched)       1    10.1          1.73 
10    122          8.37    10 Inter-row (trenched)       1     7.14        -1.23 
11    143         NA       11 Inter-row (planted)        1     4.44        NA    

【讨论】:

  • 谢谢!我回来了“错误:连接列必须存在于数据中。x ObsDOY 的问题。”。不知道我到底哪里错了。抱歉,如果我不能更具体,我知道这可能是我脚本其余部分的一千个问题之一
  • 该错误表示数据中没有名为“ObsDOY”的列。最可能的罪魁祸首是不同的标点符号(例如 Obs_DOY)或不同的大小写(例如 OBS_DOY)。如果您可以编辑问题以粘贴您的数据,就像@Peter 建议的那样,并粘贴您的代码,这将有助于弄清楚发生了什么。
  • 昨天放弃后,今天早上又试了一次,奇迹般地奏效了!非常感谢您的帮助,下次我会尝试提供更好的示例
【解决方案2】:

包含一些示例数据是一种很好的做法(我也必须学习),这样可以更轻松地重现您的问题。我冒昧地这样做是基于我了解您想要做的事情。

如果这是您的数据:

df <- data.frame(Position = c("A", "A", "B", "B", "B", "C", "C"), ObsDOY = c("Mon", "Mon", "Tue", "Tue", "Mon", "Fri", "Fri"), Lin_Flux = c(2, 3, 5, 2, 4, 1, 1))

那么这将达到你想要的结果。

df <- df %>% 
    group_by(Position, ObsDOY) %>% 
    mutate(newcol = Lin_Flux - mean(Lin_Flux))

dplyr - group_by 基本上会根据您指定的变量创建少量子样本,然后在这些子样本上完成随后的所有操作(例如使用 mean())。

p>

【讨论】:

  • 欣赏它。下次我会尝试这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 2013-05-17
  • 2016-12-18
  • 2017-04-22
  • 1970-01-01
  • 2018-02-17
  • 2013-05-19
相关资源
最近更新 更多