如何在 R 中的同一 data.frame 中按行对 data.frame 进行子集化?
How to subset a data.frame by a row in the same data.frame in R?
我想对我的 data.frame 进行子集化,以便它仅 return 具有至少 50% 值的行 <=
中特定行中的值data.frame.
df
Name A B C D
r1 2 2 2 2
r2 4 3 1 3
r3 1 1 1 2
r4 3 3 3 1
我尝试子集化的特定行是行 r1
。
我只想 return 行 r3
因为 75% 的值是 <=
行 r1
.
中的值
df
Name A B C D
r3 1 1 1 2
如有任何帮助,我们将不胜感激。如果需要更多信息,请告诉我。
使用“+”将满足的条件数逐行相加并与 3 进行比较:
subset(df, ( (A <= A[1]) + (B <= B[1]) + (C <= C[1]) + (D <= D[1]) ) >= 3 )
> subset(df, ( (A <= A[1]) + (B <= B[1]) + (C <= C[1]) + (D <= D[1]) ) >= 3 )
Name A B C D
1 r1 2 2 2 2
3 r3 1 1 1 2
如果您还想删除 'r1' 那么只需附加 [-1, ]
这可以概括为提供一个可以根据百分比标准进行测试的数字向量;它给出每行中少于第一行对应项的项目数。我需要 unlist
第一行,因为使用第三个参数作为单行数据帧失败:
rowSums(sweep(df[-1], 2, unlist(df[1,-1]), "<="))
[1] 4 2 4 2
下面是演示:
df2 <- cbind(nms = paste0("r", 1:10),
as.data.frame( matrix(sample( 1:10, 200,repl=TRUE), 10) ) )
df2
#--------------
nms V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
1 r1 8 6 10 7 3 7 2 8 4 9 9 4 5 4 8 7 2 1 6 4
2 r2 3 9 6 3 9 10 6 10 10 3 3 2 4 4 4 10 3 5 2 1
3 r3 1 7 6 8 3 5 2 3 1 5 5 4 8 3 1 6 2 10 3 7
4 r4 2 6 10 10 8 7 9 1 4 5 6 7 2 6 8 3 5 10 10 3
5 r5 5 5 7 2 5 10 2 9 2 9 4 6 1 5 8 5 8 6 3 5
6 r6 4 1 7 7 6 9 6 3 4 3 2 9 4 8 10 3 4 4 10 4
7 r7 7 1 10 4 1 2 8 5 8 8 5 5 5 6 4 10 6 9 10 6
8 r8 10 8 1 4 1 4 10 3 1 3 10 3 4 9 4 7 4 9 2 2
9 r9 3 10 9 1 10 8 8 4 7 2 7 2 9 10 3 3 7 4 10 1
10 r10 4 7 3 3 1 9 4 1 9 5 3 9 9 3 9 2 9 10 2 4
#-----------------
rowSums(sweep(df2[-1], 2, unlist(df2[1,-1]), "<="))
# [1] 20 11 15 12 12 11 11 13 10 11
rowSums(sweep(df2[-1], 2, unlist(df2[1,-1]), "<=")) >= 20*0.75
# [1] TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
df2[ rowSums(sweep(df2[-1], 2, unlist(df2[1,-1]), "<=")) >= 20*0.75 , ]
#---------
nms V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
1 r1 8 6 10 7 3 7 2 8 4 9 9 4 5 4 8 7 2 1 6 4
3 r3 1 7 6 8 3 5 2 3 1 5 5 4 8 3 1 6 2 10 3 7
我想到 apply
解决方案对于一些 R 程序员来说可能更明显:
colSums( apply(df2[-1], 1, "<=", df2[1,-1]) ) >= ncol(df2)*.7
请注意需要使用 colSums,因为它以面向列的方式`应用returns 矩阵,有时对初学者来说是个难题。
下面是通用的解决方案,也可以应用于 34 个变量:
假设:在数据集中,我们正在比较除存储 Name
.
的第一列之外的每一列
> col_names <- colnames(df)[-1]
> index <- which(df$Name == 'r1')
> values <- seq(1:nrow(df))[-index]
> row_num <- integer(0)
> for (i in values){
+ min_val <- length(col_names) / 2
+ if (length(which(df[i,col_names] <= df[index,col_names])) >= min_val)
+ row_num <- c(row_num,i)
+ }
> df[row_num,]
Name A B C D
3 r3 1 1 1 2
虽然如果数据集很大,可能需要一些时间。您可以在 data.table
包的帮助下提高性能。
我想对我的 data.frame 进行子集化,以便它仅 return 具有至少 50% 值的行 <=
中特定行中的值data.frame.
df
Name A B C D
r1 2 2 2 2
r2 4 3 1 3
r3 1 1 1 2
r4 3 3 3 1
我尝试子集化的特定行是行 r1
。
我只想 return 行 r3
因为 75% 的值是 <=
行 r1
.
df
Name A B C D
r3 1 1 1 2
如有任何帮助,我们将不胜感激。如果需要更多信息,请告诉我。
使用“+”将满足的条件数逐行相加并与 3 进行比较:
subset(df, ( (A <= A[1]) + (B <= B[1]) + (C <= C[1]) + (D <= D[1]) ) >= 3 )
> subset(df, ( (A <= A[1]) + (B <= B[1]) + (C <= C[1]) + (D <= D[1]) ) >= 3 )
Name A B C D
1 r1 2 2 2 2
3 r3 1 1 1 2
如果您还想删除 'r1' 那么只需附加 [-1, ]
这可以概括为提供一个可以根据百分比标准进行测试的数字向量;它给出每行中少于第一行对应项的项目数。我需要 unlist
第一行,因为使用第三个参数作为单行数据帧失败:
rowSums(sweep(df[-1], 2, unlist(df[1,-1]), "<="))
[1] 4 2 4 2
下面是演示:
df2 <- cbind(nms = paste0("r", 1:10),
as.data.frame( matrix(sample( 1:10, 200,repl=TRUE), 10) ) )
df2
#--------------
nms V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
1 r1 8 6 10 7 3 7 2 8 4 9 9 4 5 4 8 7 2 1 6 4
2 r2 3 9 6 3 9 10 6 10 10 3 3 2 4 4 4 10 3 5 2 1
3 r3 1 7 6 8 3 5 2 3 1 5 5 4 8 3 1 6 2 10 3 7
4 r4 2 6 10 10 8 7 9 1 4 5 6 7 2 6 8 3 5 10 10 3
5 r5 5 5 7 2 5 10 2 9 2 9 4 6 1 5 8 5 8 6 3 5
6 r6 4 1 7 7 6 9 6 3 4 3 2 9 4 8 10 3 4 4 10 4
7 r7 7 1 10 4 1 2 8 5 8 8 5 5 5 6 4 10 6 9 10 6
8 r8 10 8 1 4 1 4 10 3 1 3 10 3 4 9 4 7 4 9 2 2
9 r9 3 10 9 1 10 8 8 4 7 2 7 2 9 10 3 3 7 4 10 1
10 r10 4 7 3 3 1 9 4 1 9 5 3 9 9 3 9 2 9 10 2 4
#-----------------
rowSums(sweep(df2[-1], 2, unlist(df2[1,-1]), "<="))
# [1] 20 11 15 12 12 11 11 13 10 11
rowSums(sweep(df2[-1], 2, unlist(df2[1,-1]), "<=")) >= 20*0.75
# [1] TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
df2[ rowSums(sweep(df2[-1], 2, unlist(df2[1,-1]), "<=")) >= 20*0.75 , ]
#---------
nms V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
1 r1 8 6 10 7 3 7 2 8 4 9 9 4 5 4 8 7 2 1 6 4
3 r3 1 7 6 8 3 5 2 3 1 5 5 4 8 3 1 6 2 10 3 7
我想到 apply
解决方案对于一些 R 程序员来说可能更明显:
colSums( apply(df2[-1], 1, "<=", df2[1,-1]) ) >= ncol(df2)*.7
请注意需要使用 colSums,因为它以面向列的方式`应用returns 矩阵,有时对初学者来说是个难题。
下面是通用的解决方案,也可以应用于 34 个变量:
假设:在数据集中,我们正在比较除存储 Name
.
> col_names <- colnames(df)[-1]
> index <- which(df$Name == 'r1')
> values <- seq(1:nrow(df))[-index]
> row_num <- integer(0)
> for (i in values){
+ min_val <- length(col_names) / 2
+ if (length(which(df[i,col_names] <= df[index,col_names])) >= min_val)
+ row_num <- c(row_num,i)
+ }
> df[row_num,]
Name A B C D
3 r3 1 1 1 2
虽然如果数据集很大,可能需要一些时间。您可以在 data.table
包的帮助下提高性能。