【问题标题】:Assign observations to a group based on another vector in the same R dataframe根据同一 R 数据框中的另一个向量将观察值分配给组
【发布时间】:2016-06-11 17:38:56
【问题描述】:

我正在尝试根据网格正方形 ID 将区域分配给 R 中数据框中的观察值。我有以下数据框(df):

      year month  square
    1 2000     2      A1
    2 2000     2      B2
    3 2000     2      H5
    4 2000     2      J9
    5 2000     2      A2
    6 2000     3      N8
    7 2000     3      M9
    8 2000     3      C7

我想为“区域”添加另一列,根据方格将每个观测值分配给“北”、“东”、“南”或“西”。我尝试了以下 for 循环,但没有做任何事情,

    for(i in 1:length(df$square))  {
    for(j in 1:length(N)) {
    if(df$square[i]==N[j]){
    df$area[i]=="N"}
    }
    }

    for(i in 1:length(df$square))  {
    if(any(df$square==N)==T){
    df$area[i]=="North"}
    }

其中“N”是我创建的包含位于北方的正方形的对象,即:

    N <- c("A1","A2","B2")

我确实找到了以下相关问题,但我想知道涉及字符时是否有所不同:Assign a group number based on another column by group in R

任何帮助将不胜感激。谢谢

【问题讨论】:

  • 尝试构建一个查找“data.frame”,将每个正方形映射到其区域,然后使用类似lookup$area[match(df$square, lookup$square)]
  • df$area = NA; df$area[df$square %in% N] = "N" 将适用于您显示的单个矢量。最好的方法可能是制作一个包含areasquare 列的数据框作为查找表,然后只使用merge(或match,如上所述)。

标签: r for-loop dataframe


【解决方案1】:

我推荐第二个data.frame 将正方形与区域配对,而不是像N 这样定义向量:

df <- data.frame(year = 2000,
                 month = c(2,2,2,2,2,3,3,3),
                 square = c("A1", "B2", "H5", "J9", "A2", "N8", "M9", "C7"),
                 stringsAsFactors = FALSE)
areas <- data.frame(square = c("A1", "A2", "B1", "H5", "J9", "M9", "N8"),
                    area = c("N", "N", "N", "W", "E", "S", "S"),
                    stringsAsFactors = FALSE)

这样,只需进行合并:

merge(df, areas, by = "square", all.x = TRUE)
#   square year month area
# 1     A1 2000     2    N
# 2     A2 2000     2    N
# 3     B2 2000     2 <NA>
# 4     C7 2000     3 <NA>
# 5     H5 2000     2    W
# 6     J9 2000     2    E
# 7     M9 2000     3    S
# 8     N8 2000     3    S

NAs 是因为 areas 定义不完整。)

【讨论】:

    【解决方案2】:

    在 R 中,通常最好避免循环,尤其是嵌套循环。对于这种情况,我更喜欢sapply()

    N <- c("A1","A2","B2")
    #assume these are the other designations
    S <- c("H5", "J9")
    E <- c("N8","M9")
    W <- c("C7")
    
    mydat$area<- sapply(mydat$square, function (x){
      if (x %in% N)  return("North")
      if (x %in% S)  return("South")
      if (x %in% E)  return("East")
      if (x %in% W)  return("West")
      else NA
      }) 
    mydat
    
    year month square  area
    2000     2     A1 North
    2000     2     B2 North
    2000     2     H5 South
    2000     2     J9 South
    2000     2     A2 North
    2000     3     N8  East
    2000     3     M9  East
    2000     3     C7  West
    

    当您开始拥有大型数据集时,*apply() 函数将比 R 中的循环快得多。

    【讨论】:

    • 这很好用——正如你所说,适用于大型数据集。我可能应该在我的问题中提到数据集实际上有 >20000 行!谢谢
    【解决方案3】:
    d <- data.frame(year = rep(2000, 8), month = rep(3,8),
                square = c("A1", "B2", "H5", "J9", "A2", "N8", "M9", "C7"))
    
    N <- c("A1","A2","B2")
    
    for(i in 1:nrow(d))  {
        if (d$square[i] %in% N) {
            d$area[i] <- "North"
        }
        else (
            d$area[i] <- "Somewhere Else"
        )
    }
    

    for 循环中 else if() 语句中的层用于其他基本方向 id 向量

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多