【问题标题】:Data.table and for loopsData.table 和 for 循环
【发布时间】:2016-10-04 20:47:58
【问题描述】:

我正在处理 data.tables 的问题。基本上我在 data.table 中搜索 set_a 并检查 Average 是否大于 80 并进行一些矩阵构建。我的标准查找 set_a 值,如果它大于 80,我只想将顶部值粘贴在一起,如下所示在我的脚本中创建一个由 set_aset_b 与字母 a 连接组成的行, value,然后将另一行与set_aset_b 连接字母 b、value 追加到主表 mn 中。如果它不大于 80,我想选择由Average 降序排列的 1 和 2 值。我能够完成循环的第一部分,但对于set_abc,它不会继续。您还将看到t,我在其中尝试为循环的 else 部分创建第二个数据表,但无法像通常在 data.frames 中那样访问列的值。

Example data_set:
set_a <- c("a","a","a","a","b","b","b","b","c","c","c","c")
set_b <- c("red","red","red","red","red","red","red","red","red","red","red","red")
value <- c(42,68,90,91,22,65,89,98,78,88,91,33)
Average <- c(94,3,2,1,50,40,5,5,80,9,1,1)
a = data.frame(set_a,set_b,value,Average)
library(data.table)
a = data.table(a)

R 脚本

mn <- c() #create matrix to fill
mn0 <- c() #temp matrix
colu = unique(as.character(a$set_a))
colu2 = as.character(a$set_b)
for (i in seq_along(colu))
  {
    if (a[set_a[i] == colu[i], max(Average) > 80])#if the average is greater than 80 paste row variables in table.
  {
      mn <- (cbind(set_a[i],paste0(set_b[i],"_a"),value[i]))
      mn0 <- rbind(mn,mn0)
      mn2 <- (cbind(set_a[i],paste0(set_b[i],"_b"),value[i]))
      mn0 <- rbind(mn0,mn2)
      break
  }else

  {
    t = a[set_a == colu[i],.SD[1:2]] #create a second data table to select for
                                     #first second value  

    mn3 <- cbind(set_a[i],paste0(set_b[i],"_a"),value[i])

    mn0 <- rbind(mn0,mn3)
    mn4 <- cbind(set_a[i],paste0(set_b[i],"_b"),value[i])
    mn0 <- rbind(mn0,mn4)
  }
}

mn0

我目前的结果:

     [,1] [,2]    [,3]
[1,] "a"  "red_a" "42"
[2,] "a"  "red_b" "42"

期望的结果:

    [,1] [,2]    [,3]
[1,] "a"  "red_a" "42"
[2,] "a"  "red_b" "42"
[3,] "b"  "red_a" "22"
[4,] "b"  "red_b" "65"
[5,] "c"  "red_a" "78"
[6,] "c"  "red_b" "88"

【问题讨论】:

    标签: r for-loop


    【解决方案1】:

    if 中有一个 break。这将导致您的代码退出for-loop。另外,在else块上,需要引用临时data.table "t",否则set_a会引用data.table "a"。

    这是正确的脚本:

    mn <- c() #create matrix to fill
    mn0 <- c() #temp matrix
    colu = unique(as.character(a$set_a))
    colu2 = as.character(a$set_b)
    
    for (i in seq_along(colu))
      {
        if (a[set_a == colu[i], max(Average) > 80])#if the average is greater than 80 paste row variables in table.
      {
          mn <- (cbind(set_a[i],paste0(set_b[i],"_a"),value[i]))
          mn0 <- rbind(mn,mn0)
          mn2 <- (cbind(set_a[i],paste0(set_b[i],"_b"),value[i]))
          mn0 <- rbind(mn0,mn2)
      }else
    
      {
        t = a[set_a == colu[i],.SD[1:2]] #create a second data table to select for
                                         #first second value  
    
        mn3 <- cbind(as.character(t$set_a[1]),paste0(t$set_b[1],"_a"),t$value[1])
    
        mn0 <- rbind(mn0,mn3)
        mn4 <- cbind(as.character(t$set_a[2]),paste0(t$set_b[2],"_b"),t$value[2])
        mn0 <- rbind(mn0,mn4)
      }
    }
    
    mn0
    

    【讨论】:

    • 谢谢。我没有意识到您可以使用 data.tables 进行 $ 选择。
    猜你喜欢
    • 2023-04-09
    • 2023-04-02
    • 2019-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多