使用数据表在R中进行另一个数据表的掩码/过滤

4

我有一个数据表格,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

我想使用它来遮蔽另一个数据表,其sigma值低于阈值,比如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] - akrun
3个回答

4
我们可以使用基础的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的行,并在其中插入NA

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>

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 <- setDT(A)[, Reduce(&, lapply(.SD, <, 2)), .SDcols = nm1] 不起作用:错误:在“i1 <- setDT(A_sigma)[, Reduce(&',lapply(.SD,<”中意外出现 '<'。` - OverFlow Police
我是说:“错误:在“i1 <- setDT(A)[, Reduce(&, lapply(.SD, <”中出现意外的‘<’”。 - OverFlow Police
抱歉,反引号没有复制,请测试更新后的代码。 - akrun
你的输出如下: 年份 位置 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你缺少两个值,一个在第四行的 sigma_1 列,另一个在 sigma_2 列,它们都小于 2。 - OverFlow Police
@NoLie 抱歉,我在回答时不知道预期的输出。 - akrun
没问题,akrun。谢谢大家! - OverFlow Police

3

简单的基于R语言的解决方案:

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

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

然后使用向量化逻辑表达式A[-(1:2)]>=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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接