【问题标题】:Dynamically subset and mutate data.table?动态子集和变异data.table?
【发布时间】:2020-06-21 18:11:21
【问题描述】:

我有 2 个单独的 DF,我想根据 dat1 中的非 NA 列改变 dat2 中的 2 个新列(“Avg_of_nonNA”和一个“Cols”以跟踪其使用的列)。我需要 dat2 的一个子集,因为矩阵是密集的,而 dat1 是稀疏的(所以我可以利用稀疏性)。匹配列的唯一方法是匹配名称中的公共元素:在我的例子中是 (0-1,1-2,2-3,3-4)。其余的列名都是乱码。它需要字符串拆分和匹配——导致很多问题,因为我不能将东西链接在一起,因为每一行都有不同的列组合来平均(简化了虚拟示例)。我确实有一个可行的解决方案,但是在我的 1M+ 行中速度非常慢。这是解决方案:

我正在寻找一种摆脱 for 循环的方法。有什么建议吗?

for (z in 1:5) {
  relevant_cols=dat1[z,] %>%
    select_if(~!all(is.na(.))) %>%
    names %>% strsplit(.,'_') %>% map(.,2) %>% unlist()
  id=dat1[z,'ID']$`ID`
  dat2[`ID`== id,`:=`(Avg_of_nonNA = (mean(as.numeric(.SD))),Cols=paste0(relevant_cols,collapse='/')), .SDcols=names(dat2) %like% paste0(relevant_cols,collapse='|')]
}
下面的数据
> dat1
   ID gjfkg_0-1_fkjdk_fjdkd jdfsje_1-2_fhks_ejfskj dfjs_2-3_vjskf_wqew gdlkrzc_3-4_rjrkj Avg_of_nonNA_otherDT
1:  1                  2.23                   1.37                  NA                NA                  1.5
2:  2                  1.98                     NA                  NA             1.760                  6.5
3:  3                    NA                   4.45               9.350             3.320                 11.0
4:  4                    NA                     NA               6.642             2.019                 15.5
5:  5                    NA                   3.21               3.677                NA                 18.5
> dat2
   ID ewrwer_0-1_iopi_opop erewtt_1-2_rueiwu_vcvbc erewr_2-3_iirew_rewr mnmn_3-4_cxzxzc_gjd
1:  1                    1                       2                    3                   4
2:  2                    5                       6                    7                   8
3:  3                    9                      10                   11                  12
4:  4                   13                      14                   15                  16
5:  5                   17                      18                   19                  20


dput(dat1)
        structure(list(ID = 1:5, `gjfkg_0-1_fkjdk_fjdkd` = c(2.23, 1.98, 
        NA, NA, NA), `jdfsje_1-2_fhks_ejfskj` = c(1.37, NA, 4.45, NA, 
        3.21), `dfjs_2-3_vjskf_wqew` = c(NA, NA, 9.35, 6.642, 3.677), 
            `gdlkrzc_3-4_rjrkj` = c(NA, 1.76, 3.32, 2.019, NA)), row.names = c(NA, -5L), class = c("data.table", 
        "data.frame"))
dput(dat2)
        structure(list(ID = 1:5, `ewrwer_0-1_iopi_opop` = c(1L, 5L, 9L, 
        13L, 17L), `erewtt_1-2_rueiwu_vcvbc` = c(2L, 6L, 10L, 14L, 18L
        ), `erewr_2-3_iirew_rewr` = c(3L, 7L, 11L, 15L, 19L), `mnmn_3-4_cxzxzc_gjd` = c(4L, 
        8L, 12L, 16L, 20L)), row.names = c(NA, -5L), class = c("data.table", 
        "data.frame"))

预期输出:

【问题讨论】:

    标签: r dplyr data.table


    【解决方案1】:

    这是一个选项:

    setDT(dat1)
    setDT(dat2)
    nm <- sapply(strsplit(names(dat1[, -"ID"]), "_"), `[[`, 2L)
    dat2[, c("Avg_of_nonNA_otherDT", "Cols") := {
        nas <- is.na(dat1[,-"ID"])
    
        m <- col(nas)
        m[] <- nm[m]
        m[nas] <- ""
    
        .(rowMeans(.SD * NA^nas, na.rm=TRUE), 
            gsub("\\s+", "/", trimws(do.call(paste, as.data.frame(m)))))
    }, .SDcols=-"ID"]
    

    输出:

       ID ewrwer_0-1_iopi_opop erewtt_1-2_rueiwu_vcvbc erewr_2-3_iirew_rewr mnmn_3-4_cxzxzc_gjd Avg_of_nonNA_otherDT        Cols
    1:  1                    1                       2                    3                   4                  1.5     0-1/1-2
    2:  2                    5                       6                    7                   8                  6.5     0-1/3-4
    3:  3                    9                      10                   11                  12                 11.0 1-2/2-3/3-4
    4:  4                   13                      14                   15                  16                 15.5     2-3/3-4
    5:  5                   17                      18                   19                  20                 18.5     1-2/2-3
    

    【讨论】:

      猜你喜欢
      • 2020-10-12
      • 1970-01-01
      • 1970-01-01
      • 2013-01-08
      • 2022-01-15
      • 2014-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多