Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 在数据框中搜索接近数字列表的值_R_Search_Dataframe - Fatal编程技术网

R 在数据框中搜索接近数字列表的值

R 在数据框中搜索接近数字列表的值,r,search,dataframe,R,Search,Dataframe,注意:这个问题中的“数据帧”实际上是矩阵。我保留了措辞,以便答案仍然有意义,因为解决方案同时适用于数据帧和矩阵 我有一个数据框,包含质量及其相应强度的列表: > df <- cbind(c(3.43534, 5.324, 9.322, 123.234), c(31, 4214, 112, 44)) > colnames(df) <- c("Mass", "I") > df Mass I [1,] 3.43534 31 [2,]

注意:这个问题中的“数据帧”实际上是矩阵。我保留了措辞,以便答案仍然有意义,因为解决方案同时适用于数据帧和矩阵

我有一个数据框,包含质量及其相应强度的列表:

> df <- cbind(c(3.43534, 5.324, 9.322, 123.234), c(31, 4214, 112, 44))
> colnames(df) <- c("Mass", "I")
> df
          Mass    I
[1,]   3.43534   31
[2,]   5.32400 4214
[3,]   9.32200  112
[4,] 123.23400   44
现实生活中的数据有数千行,因此不幸的是循环速度太慢。

这应该可以做到:

tol <- 0.2
compounds[which(do.call(pmin,as.data.frame(abs(outer(compounds$Mass, df$Mass, "-")))) < tol),]
##  Mass Compound
##1 3.39        A
##3 9.31        C
这样会快一点

数据:

df <- structure(list(Mass = c(3.43534, 5.324, 9.322, 123.234), I = c(31, 
4214, 112, 44)), .Names = c("Mass", "I"), row.names = c(NA, -4L
), class = "data.frame")
##       Mass    I
##1   3.43534   31
##2   5.32400 4214
##3   9.32200  112
##4 123.23400   44

compounds <- structure(list(Mass = c(3.39, 102.93, 9.31), Compound = structure(1:3, .Label = c("A", 
"B", "C"), class = "factor")), .Names = c("Mass", "Compound"), row.names = c(NA, 
-3L), class = "data.frame")
##    Mass Compound
##1   3.39        A
##2 102.93        B
##3   9.31        C
##4 144.00        D

df关于如何连接两个数据集,然后根据所需条件进行过滤,我可以想出一个解决方案:

df <- data.frame(Mass = c(3.43534, 5.324, 9.322, 123.234),
                 I = c(31, 4214, 112, 44))
compounds <- data.frame(Mass = c(3.39, 102.93, 9.310, 144.00),
                        Compound = c("A", "B", "C", "D"),
                        stringsAsFactors = FALSE)

df <- expand.grid(df$Mass, 1:nrow(compounds))
df <- cbind(Var1 = df$Var1, compounds[df$Var2, ])
unique(df[(df$Mass > df$Var1 - 0.2 & df$Mass < df$Var1 + 0.2),
           c('Mass', 'Compound')])

df这些是矩阵,不是数据帧。抱歉,你是对的。我犯了这个错误,因为我使用的完整数据集是data.frame,尽管爱照的解决方案仍然有效。现在将更改措辞。非常有趣的解决方案,尽管由于
do.call.
谢谢大家!只是测试每个解决方案,看看哪个在全尺寸数据集上运行得更快。@Gopala:事实上,我不这么认为,因为
do.call
用于调用
pmin
,它与列表(即距离矩阵的列)平行。这就是为什么我们使用
as.data.frame
进行转换,它给出了列列表。它必须逐行转换,但这与n平方循环不同。所以,我同意它更优化。@DGreenwood:是的,第二个解决方案没有计算最小距离;它只查找距离小于
df
中任何行的公差的
化合物
;因此速度更快。注意这一点,因为根据数据大小,它可能会占用太多内存。错误:找不到对象“x”。对此表示抱歉。我将名称从x更改为df,但没有完全修复它。现在,编辑。
compounds[unique(which(abs(outer(compounds$Mass, df$Mass, "-")) < tol, arr.ind=TRUE)[,1]),]
##  Mass Compound
##1 3.39        A
##3 9.31        C
df <- structure(list(Mass = c(3.43534, 5.324, 9.322, 123.234), I = c(31, 
4214, 112, 44)), .Names = c("Mass", "I"), row.names = c(NA, -4L
), class = "data.frame")
##       Mass    I
##1   3.43534   31
##2   5.32400 4214
##3   9.32200  112
##4 123.23400   44

compounds <- structure(list(Mass = c(3.39, 102.93, 9.31), Compound = structure(1:3, .Label = c("A", 
"B", "C"), class = "factor")), .Names = c("Mass", "Compound"), row.names = c(NA, 
-3L), class = "data.frame")
##    Mass Compound
##1   3.39        A
##2 102.93        B
##3   9.31        C
##4 144.00        D
df <- data.frame(Mass = c(3.43534, 5.324, 9.322, 123.234),
                 I = c(31, 4214, 112, 44))
compounds <- data.frame(Mass = c(3.39, 102.93, 9.310, 144.00),
                        Compound = c("A", "B", "C", "D"),
                        stringsAsFactors = FALSE)

df <- expand.grid(df$Mass, 1:nrow(compounds))
df <- cbind(Var1 = df$Var1, compounds[df$Var2, ])
unique(df[(df$Mass > df$Var1 - 0.2 & df$Mass < df$Var1 + 0.2),
           c('Mass', 'Compound')])