在不删除值的情况下对数据框进行阈值处理
Thresholding a data frame without removing values
我有一个数据框,它包含一个非唯一标识符 (ID) 和该 ID 内某些 属性 对象的度量值,如下所示:
ID Sph
A 1.0
A 1.2
A 1.1
B 0.5
B 1.8
C 2.2
C 1.1
D 2.1
D 3.0
首先,我使用 table(df$ID)
,即 A=3
、B=2
、C=2
和 D=2
得到每个 ID 作为 X 的实例数。接下来,我想在获取实例数后在 "Sph" 类别中应用一个阈值,限制为 Sph
值超过阈值的行。例如,对于阈值 2.0,我会使用 thold=df[df$Sph>2.0,]
。最后,我想用上面使用 table
计算的 X
值替换 ID
列。例如,"Sph" 列中的阈值为 1.1,我想要以下输出:
ID Sph
3 1.0
2 1.8
2 2.2
2 2.1
2 3.0
换句话说,在使用 table()
获得与 ID 出现次数相对应的 x 值之后,比如 3,我想将该数字分配给该 ID 中的每个值, Y,这超过了某个阈值。
你的问题有些不一致,你没有给出可重现的例子,但这是我的尝试。
我喜欢使用 dplyr 库,在这种情况下我不得不打破一个 sapply,也许有人可以改进我的答案。
这是简短的版本:
library(dplyr)
#your data
x <- data.frame(ID=c(rep("A",3),rep("B",2),rep("C",2),rep("D",2)),Sph=c(1.0,1.2,1.1,0.5,1.8,2.2,1.1,2.1,3.0),stringsAsFactors = FALSE)
#lookup table
y <- summarise(group_by(x,ID), IDn=n())
#fill in original table
x$IDn <- sapply(x$ID,function(z) as.integer(y[y$ID==z,"IDn"]))
#filter for rows where Sph greater or equal to 1.1
x <- x %>% filter(Sph>=1.1)
#done
x
这是带有解释性输出的较长版本:
> library(dplyr)
> #your data
> x <- data.frame(ID=c(rep("A",3),rep("B",2),rep("C",2),rep("D",2)),Sph=c(1.0,1.2,1.1,0.5,1.8,2.2,1.1,2.1,3.0),stringsAsFactors = FALSE)
> x
ID Sph
1 A 1.0
2 A 1.2
3 A 1.1
4 B 0.5
5 B 1.8
6 C 2.2
7 C 1.1
8 D 2.1
9 D 3.0
>
> #lookup table
> y <- summarise(group_by(x,ID), IDn=n())
> y
Source: local data frame [4 x 2]
ID IDn
1 A 3
2 B 2
3 C 2
4 D 2
>
> #fill in original table
> x$IDn <- sapply(x$ID,function(z) as.integer(y[y$ID==z,"IDn"]))
> x
ID Sph IDn
1 A 1.0 3
2 A 1.2 3
3 A 1.1 3
4 B 0.5 2
5 B 1.8 2
6 C 2.2 2
7 C 1.1 2
8 D 2.1 2
9 D 3.0 2
>
> #filter for rows where Sph greater or equal to 1.1
> x <- x %>% filter(Sph>=1.1)
>
> #done
> x
ID Sph IDn
1 A 1.2 3
2 A 1.1 3
3 B 1.8 2
4 C 2.2 2
5 C 1.1 2
6 D 2.1 2
7 D 3.0 2
您实际上可以在计算 X
和 thold
之后一步完成此操作,就像您在问题中所做的那样:
X <- table(df$ID)
thold <- df[df$Sph > 1.1,]
thold$ID <- X[as.character(thold$ID)]
thold
# ID Sph
# 2 3 1.2
# 5 2 1.8
# 6 2 2.2
# 8 2 2.1
# 9 2 3.0
基本上你在你构建的 table X
中查找每个 ID 值的频率。
我有一个数据框,它包含一个非唯一标识符 (ID) 和该 ID 内某些 属性 对象的度量值,如下所示:
ID Sph
A 1.0
A 1.2
A 1.1
B 0.5
B 1.8
C 2.2
C 1.1
D 2.1
D 3.0
首先,我使用 table(df$ID)
,即 A=3
、B=2
、C=2
和 D=2
得到每个 ID 作为 X 的实例数。接下来,我想在获取实例数后在 "Sph" 类别中应用一个阈值,限制为 Sph
值超过阈值的行。例如,对于阈值 2.0,我会使用 thold=df[df$Sph>2.0,]
。最后,我想用上面使用 table
计算的 X
值替换 ID
列。例如,"Sph" 列中的阈值为 1.1,我想要以下输出:
ID Sph
3 1.0
2 1.8
2 2.2
2 2.1
2 3.0
换句话说,在使用 table()
获得与 ID 出现次数相对应的 x 值之后,比如 3,我想将该数字分配给该 ID 中的每个值, Y,这超过了某个阈值。
你的问题有些不一致,你没有给出可重现的例子,但这是我的尝试。
我喜欢使用 dplyr 库,在这种情况下我不得不打破一个 sapply,也许有人可以改进我的答案。
这是简短的版本:
library(dplyr)
#your data
x <- data.frame(ID=c(rep("A",3),rep("B",2),rep("C",2),rep("D",2)),Sph=c(1.0,1.2,1.1,0.5,1.8,2.2,1.1,2.1,3.0),stringsAsFactors = FALSE)
#lookup table
y <- summarise(group_by(x,ID), IDn=n())
#fill in original table
x$IDn <- sapply(x$ID,function(z) as.integer(y[y$ID==z,"IDn"]))
#filter for rows where Sph greater or equal to 1.1
x <- x %>% filter(Sph>=1.1)
#done
x
这是带有解释性输出的较长版本:
> library(dplyr)
> #your data
> x <- data.frame(ID=c(rep("A",3),rep("B",2),rep("C",2),rep("D",2)),Sph=c(1.0,1.2,1.1,0.5,1.8,2.2,1.1,2.1,3.0),stringsAsFactors = FALSE)
> x
ID Sph
1 A 1.0
2 A 1.2
3 A 1.1
4 B 0.5
5 B 1.8
6 C 2.2
7 C 1.1
8 D 2.1
9 D 3.0
>
> #lookup table
> y <- summarise(group_by(x,ID), IDn=n())
> y
Source: local data frame [4 x 2]
ID IDn
1 A 3
2 B 2
3 C 2
4 D 2
>
> #fill in original table
> x$IDn <- sapply(x$ID,function(z) as.integer(y[y$ID==z,"IDn"]))
> x
ID Sph IDn
1 A 1.0 3
2 A 1.2 3
3 A 1.1 3
4 B 0.5 2
5 B 1.8 2
6 C 2.2 2
7 C 1.1 2
8 D 2.1 2
9 D 3.0 2
>
> #filter for rows where Sph greater or equal to 1.1
> x <- x %>% filter(Sph>=1.1)
>
> #done
> x
ID Sph IDn
1 A 1.2 3
2 A 1.1 3
3 B 1.8 2
4 C 2.2 2
5 C 1.1 2
6 D 2.1 2
7 D 3.0 2
您实际上可以在计算 X
和 thold
之后一步完成此操作,就像您在问题中所做的那样:
X <- table(df$ID)
thold <- df[df$Sph > 1.1,]
thold$ID <- X[as.character(thold$ID)]
thold
# ID Sph
# 2 3 1.2
# 5 2 1.8
# 6 2 2.2
# 8 2 2.1
# 9 2 3.0
基本上你在你构建的 table X
中查找每个 ID 值的频率。