【问题标题】:Use a data table to mask/filter another data table in R使用数据表来屏蔽/过滤 R 中的另一个数据表
【发布时间】:2019-04-29 16:52:00
【问题描述】:

我有一个数据表,A 喜欢:

year          location    sigma_NN_1 sigma_NN_2 sigma_NN_3
2076 43.59375_-116.78125  1.4681173   1.664289   1.735974
2077 43.59375_-116.78125  1.3798515   1.550524   1.551269
2078 43.59375_-116.78125  0.7934367   1.064248   1.177981
2079 43.59375_-116.78125  1.8235574   1.991018   2.288402
2080 43.59375_-116.78125  2.5560329   2.578093   2.589334

我想用它来屏蔽另一个数据表,其中 sigmas 的值低于阈值,比如说 2。假设我的第二个数据表是 B

year            location       location_NN_1      location_NN_2      location_NN_3
2076 43.59375_-116.78125  41.15625_-90.65625 41.21875_-90.65625 41.15625_-90.65625
2077 43.59375_-116.78125  43.34375_-78.15625 43.34375_-78.21875 43.28125_-78.15625
2078 43.59375_-116.78125  41.34375_-90.78125 41.21875_-90.65625 41.53125_-73.96875
2079 43.59375_-116.78125 43.53125_-116.78125 41.34375_-90.78125 41.71875_-74.15625
2080 43.59375_-116.78125  41.34375_-90.78125 41.96875_-86.21875 41.21875_-90.65625

所以,我想要B[A<2] 之类的东西,但显然这不起作用,否则我不会在这里。

有什么建议吗?

预期输出:

输出

year            location       location_NN_1      location_NN_2      location_NN_3
2076 43.59375_-116.78125  41.15625_-90.65625 41.21875_-90.65625 41.15625_-90.65625
2077 43.59375_-116.78125  43.34375_-78.15625 43.34375_-78.21875 43.28125_-78.15625
2078 43.59375_-116.78125  41.34375_-90.78125 41.21875_-90.65625 41.53125_-73.96875
2079 43.59375_-116.78125 43.53125_-116.78125 41.34375_-90.78125                 NA
2080 43.59375_-116.78125                  NA                 NA                 NA

目标是找到数据表A中对应sigma小于2的位置。

【问题讨论】:

  • 你可能需要i1 <- setDT(A)[, Reduce('&', lapply(.SD, , 2)), .SDcols = 3:5]; B[i1]

标签: r filter


【解决方案1】:

我们可以使用基本 R 子集来识别B 的适当单元格,并将它们替换为NA。此方法要求AB 中的列顺序相同。

我们可以在dfa 上使用一个简单的条件语句来查找 sigma 值不小于 2 的单元格。由于我们不想将条件应用于年份和条件列,因此我们在应用之前将它们子集条件:

!(dfa[-c(1,2)] < 2)
     sigma_NN_1 sigma_NN_2 sigma_NN_3
[1,]      FALSE      FALSE      FALSE
[2,]      FALSE      FALSE      FALSE
[3,]      FALSE      FALSE      FALSE
[4,]      FALSE      FALSE       TRUE
[5,]       TRUE       TRUE       TRUE

这会返回一个逻辑矩阵,我们可以使用它来对B 进行子集化以替换值。这里发生的是我们将B 子集两次:首先我们忽略年份和位置列以仅获取位置列,然后我们使用前面的条件选择匹配sigma 值不小于2 的行并插入@987654329 @进去:

dfb[-c(1,2)][!(dfa[-c(1,2)] < 2)] <- NA
dfb

  year            location       location_NN_1      location_NN_2      location_NN_3
1 2076 43.59375_-116.78125  41.15625_-90.65625 41.21875_-90.65625 41.15625_-90.65625
2 2077 43.59375_-116.78125  43.34375_-78.15625 43.34375_-78.21875 43.28125_-78.15625
3 2078 43.59375_-116.78125  41.34375_-90.78125 41.21875_-90.65625 41.53125_-73.96875
4 2079 43.59375_-116.78125 43.53125_-116.78125 41.34375_-90.78125               <NA>
5 2080 43.59375_-116.78125                <NA>               <NA>               <NA>

【讨论】:

    【解决方案2】:

    简单的基础 R 解决方案:

    B[-(1:2)][A[-(1:2)]>=2] <- NA
    

    选择除第一和第二B[-(1:2)] 之外的所有列。

    然后使用矢量化逻辑表达式A[-(1:2)]&gt;=2 将正确的元素设置为NA

    结果:

      year            location       location_NN_1      location_NN_2      location_NN_3
    1 2076 43.59375_-116.78125  41.15625_-90.65625 41.21875_-90.65625 41.15625_-90.65625
    2 2077 43.59375_-116.78125  43.34375_-78.15625 43.34375_-78.21875 43.28125_-78.15625
    3 2078 43.59375_-116.78125  41.34375_-90.78125 41.21875_-90.65625 41.53125_-73.96875
    4 2079 43.59375_-116.78125 43.53125_-116.78125 41.34375_-90.78125               <NA>
    5 2080 43.59375_-116.78125                <NA>               <NA>               <NA>
    

    【讨论】:

      【解决方案3】:

      假设这些data.table对象,并假设'A'中'sigma'列的行数都应该小于阈值2。

      library(data.table)
      nm1 <- grep("sigma", names(A), value = TRUE)
      i1 <- setDT(A)[, Reduce(`&`, lapply(.SD, `<`, 2)), .SDcols = nm1]
      setDT(B)[i1] 
      

      更新

      基于预期输出

      nm2 <- grep("sigma", names(A))
      B[, (nm2) := Map(function(x, y) replace(x, y >= 2, NA_character_),
              .SD, A[, nm2, with = FALSE]), .SDcols = nm2][]
      # year            location       location_NN_1      location_NN_2      location_NN_3
      #1: 2076 43.59375_-116.78125  41.15625_-90.65625 41.21875_-90.65625 41.15625_-90.65625
      #2: 2077 43.59375_-116.78125  43.34375_-78.15625 43.34375_-78.21875 43.28125_-78.15625
      #3: 2078 43.59375_-116.78125  41.34375_-90.78125 41.21875_-90.65625 41.53125_-73.96875
      #4: 2079 43.59375_-116.78125 43.53125_-116.78125 41.34375_-90.78125               <NA>
      #5: 2080 43.59375_-116.78125                <NA>               <NA>               <NA>
      

      数据

      A <- structure(list(year = 2076:2080, location = c("43.59375_-116.78125", 
      "43.59375_-116.78125", "43.59375_-116.78125", "43.59375_-116.78125", 
      "43.59375_-116.78125"), sigma_NN_1 = c(1.4681173, 1.3798515, 
      0.7934367, 1.8235574, 2.5560329), sigma_NN_2 = c(1.664289, 1.550524, 
      1.064248, 1.991018, 2.578093), sigma_NN_3 = c(1.735974, 1.551269, 
      1.177981, 2.288402, 2.589334)), class = "data.frame", row.names = c(NA, 
      -5L))
      
      B <- structure(list(year = 2076:2080, location = c("43.59375_-116.78125", 
      "43.59375_-116.78125", "43.59375_-116.78125", "43.59375_-116.78125", 
      "43.59375_-116.78125"), location_NN_1 = c("41.15625_-90.65625", 
      "43.34375_-78.15625", "41.34375_-90.78125", "43.53125_-116.78125", 
      "41.34375_-90.78125"), location_NN_2 = c("41.21875_-90.65625", 
      "43.34375_-78.21875", "41.21875_-90.65625", "41.34375_-90.78125", 
      "41.96875_-86.21875"), location_NN_3 = c("41.15625_-90.65625", 
      "43.28125_-78.15625", "41.53125_-73.96875", "41.71875_-74.15625", 
      "41.21875_-90.65625")), class = "data.frame", row.names = c(NA, 
      -5L))
      

      【讨论】:

      • i1 &lt;- setDT(A)[, Reduce(&, lapply(.SD, &lt;, 2)), .SDcols = nm1] 不起作用:Error: unexpected '&lt;' in "i1 &lt;- setDT(A_sigma)[, Reduce(&, lapply(.SD, &lt;"
      • 我的意思是:Error: unexpected '&lt;' in "i1 &lt;- setDT(A)[, Reduce(&, lapply(.SD, &lt;"
      • 抱歉反引号没有复制'你可以测试更新的代码'
      • your output looks like ` year location location_NN_1 location_NN_2 location_NN_3 1: 2076 43.59375_-116.78125 41.15625_-90.65625 41.21875_-90.65625 41.15625_-90.65625 2: 2077 43.59375_-116.78125 43.34375_-78.15625 43.34375_ -78.21875 43.28125_-78.15625 3: 2078 43.59375_-116.78125 41.34375_-90.78125 41.21875_-90.65625 41.53125_-73.96875` You are missing two values one in sigma_1 and one in sigma_2 column, both in 4th row.小于 2
      • @NoLie 对不起,我写答案时不知道预期的输出。
      猜你喜欢
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      • 2022-10-01
      • 1970-01-01
      • 2019-01-13
      • 2013-03-27
      • 1970-01-01
      相关资源
      最近更新 更多