繁体   English   中英

如何在R中的同一data.frame中按行子集data.frame?

[英]How to subset a data.frame by a row in the same data.frame in R?

我想我的子集,以便data.frame它只会返回他们的值的至少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行。 我只想返回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

在我看来,对于某些R程序员来说, apply解决方案可能看起来更加明显:

 colSums( apply(df2[-1], 1, "<=", df2[1,-1]) ) >= ncol(df2)*.7

注意需要使用colSums,因为`apply以面向列的方式应用返回矩阵的方式,有时是初学者的难题。

这是通用解决方案,也可以应用于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包来提高性能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM