【问题标题】:New variable based on conditional arithmetic by group基于分组条件算术的新变量
【发布时间】:2014-03-26 16:35:20
【问题描述】:

我有一个 data.frame df 我想在其中创建一个新变量,该变量是另一个按组的比例。那是对于每个SpeciesIDPlotSub配对我想通过Type找到Area的比例。如果Type = 0,则PropArea == 1,如果Type 不等于0(即1 或2),则例如PropArea = Area(类型1)/Area (类型 0)。下面是一个示例 data.frame。我知道如何使用 excel 中的 if 语句来执行此操作,但希望在 r 中找到一种方法来执行此操作。

df <- structure(list(Species = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("BFGR", "RNNN"), class = "factor"), 
    ID = c(201L, 201L, 201L, 201L, 201L, 201L, 219L, 219L, 219L, 
    219L, 219L, 219L, 220L, 220L), Plot = c(1L, 1L, 2L, 2L, 1L, 
    1L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L), Sub = c(2L, 2L, 2L, 
    2L, 3L, 3L, 10L, 10L, 11L, 11L, 12L, 12L, 13L, 13L), Type = c(0L, 
    1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 2L), Area = c(0.78, 
    0.445, 0.023, 0.015, 0.79, 0.235, 1.29, 1.29, 2.555, 1.065, 
    1.365, 1.365, 2.678, 1.305), PropArea = c(1, 0.570512821, 
    1, 0.652173913, 1, 0.297468354, 1, 1, 1, 0.416829746, 1, 
    1, 1, 0.487303958)), .Names = c("Species", "ID", "Plot", 
"Sub", "Type", "Area", "PropArea"), class = "data.frame", row.names = c(NA, 
-14L))

## A more complete data set    
 df_more <- structure(list(Species = structure(c(3L, 3L, 3L, 3L, 3L, 3L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("ACRU", "DIVI", 
"LIST", "LITU", "PEPA", "QULA"), class = "factor"), ID = c(205L, 
205L, 205L, 205L, 205L, 205L, 219L, 219L, 219L, 219L, 219L, 219L, 
219L, 219L, 219L, 219L, 219L, 219L, 219L, 219L, 219L, 219L, 219L, 
219L, 219L, 219L, 219L, 219L, 219L, 219L, 219L, 219L, 219L, 219L, 
219L, 219L, 221L, 221L, 222L, 222L, 222L, 222L, 222L, 222L, 222L, 
222L, 222L, 222L, 222L, 222L, 222L, 222L, 222L, 222L, 222L, 222L, 
222L, 222L, 222L, 222L, 222L, 222L, 227L, 227L, 227L, 227L, 227L, 
227L, 227L, 227L, 227L, 227L, 227L, 227L, 228L, 228L, 228L, 228L, 
228L, 228L, 228L, 228L, 228L, 228L, 228L, 228L, 228L, 228L, 228L, 
228L, 228L, 228L, 228L, 228L, 228L, 228L, 228L, 229L, 229L, 229L, 
229L, 229L, 229L, 229L, 229L, 229L, 229L, 229L, 229L, 229L, 229L
), Plot = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L), Sub = c(2L, 2L, 3L, 3L, 4L, 4L, 2L, 2L, 2L, 3L, 3L, 
3L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L, 10L, 
10L, 11L, 11L, 12L, 12L, 13L, 13L, 14L, 14L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 
5L, 5L, 5L, 5L, 5L, 5L, 2L, 2L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 
6L, 6L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 6L, 6L, 7L, 7L, 7L, 8L, 
8L, 8L, 9L, 9L, 9L, 10L, 10L, 11L, 11L, 2L, 2L, 2L, 3L, 3L, 3L, 
4L, 4L, 5L, 5L, 6L, 6L, 6L, 7L), Type = c(0L, 1L, 0L, 1L, 0L, 
1L, 2L, 0L, 1L, 2L, 0L, 1L, 2L, 0L, 1L, 2L, 0L, 1L, 0L, 1L, 0L, 
1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 
1L, 0L, 0L, 1L, 1L, 2L, 2L, 0L, 0L, 1L, 1L, 2L, 2L, 0L, 0L, 1L, 
1L, 2L, 2L, 0L, 0L, 1L, 1L, 2L, 2L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 
1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 2L, 
0L, 1L, 2L, 0L, 1L, 2L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 2L, 0L, 
1L, 2L, 0L, 1L, 1L, 2L, 0L, 1L, 2L, 0L), Area = c(5.67, 3.24, 
6.65, 4.26, 10.24, 1.31, 1.12, 1.23, 1.23, 0.88, 0.86, 0.86, 
0.11, 1.36, 1.36, 1.17, 2.33, 2.33, 1.15, 1.15, 1.23, 1.23, 1.27, 
1.27, 0.97, 0.97, 1.39, 1.39, 1.07, 1.07, 1.49, 1.49, 1.33, 1.33, 
2.35, 2.35, 1.8, 1.8, 7.5, 7.42, 6.35, 6.82, 0.37, 0.48, 8.67, 
8.57, 5.47, 5.66, 2.35, 2.42, 11.99, 12.8, 6.18, 6.19, 2.56, 
2.71, 25.77, 25.6, 16.01, 16.56, 3.36, 3.35, 1.08, 0.12, 5.34, 
5.34, 6.15, 6.15, 6.93, 6.93, 8.91, 8.91, 10.91, 10.91, 2.31, 
1.21, 3.2, 2.42, 2.41, 2.41, 2.32, 2.32, 2.48, 2.48, 0.7, 2.89, 
2.89, 1.27, 3.66, 3.66, 0.75, 8, 8, 8.85, 8.85, 11.22, 11.22, 
5.08, 2.96, 0.22, 5, 3.01, 0.92, 6.94, 3.88, 4.48, 1.18, 9.03, 
4.19, 0.5, 9.97)), .Names = c("Species", "ID", "Plot", "Sub", 
"Type", "Area"), row.names = c(NA, 111L), class = "data.frame")

【问题讨论】:

    标签: r dataframe conditional plyr


    【解决方案1】:

    只要您对使用 data.frame 没问题,这应该可以工作:

    library(plyr)
    df2 <- ddply(df_more, .(Species, ID, Plot, Sub), function(groupdf) {
      denominator <- groupdf[groupdf$Type==0,"Area"]
      if(length(denominator) == 0) denominator <- groupdf[groupdf$Type==1,"Area"]
      transform(groupdf, PropArea=Area/denominator)
    })
    

    如果你想保持相同的顺序,添加这些行:

    df1 <- df2[match(
      interaction(df[c("Species", "ID", "Plot", "Sub", "Type")]), 
      interaction(df2[c("Species", "ID", "Plot", "Sub", "Type")])),]
    

    【讨论】:

    • 这在上面的数据子集上效果很好,但是,在完整数据集Error in data.frame(list(Species = c(2L, 2L), ID = c(229L, 229L), Plot = c(1L ,:arguments imply differing number of rows: 2, 0 上使用时出现以下错误我将包含上面的完整数据集。有什么建议么? ——
    • 看起来您有没有类型 0 的 Species、ID、Plot、Sub 组合。(要查看此内容,请将 if(length(groupdf[groupdf$Type==0,"Area"]) == 0) { print(groupdf) ; stop("didn't find a type 0 in this group") } 添加到 ddply 函数参数的开头)。当组中没有Type==0时你想做什么?
    • 谢谢,如果没有Type == 0,那么Type == 1,应该改用Type == 1,但是我可以手动更改,因为不是很多。
    • 那行得通。或者您可以尝试上面的编辑版本,如果没有 Type==0,它将分母切换为 Type==1。
    【解决方案2】:

    如果您可以保证 0s 与 1s 和 2s 像在您的示例中一样,您可以使用 ifelse

    df$PropArea <- ifelse(df$Type == 0, 1, df$Area / c(1, df$Area[-nrow(df)]))
    

    【讨论】:

      【解决方案3】:

      df_more 数据集中有重复项。 例如。 DIVI/22/1/2/0 的面积为 7.50 和 7.42。 这会导致错误。

      【讨论】:

        猜你喜欢
        • 2019-11-21
        • 2021-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多