【问题标题】:Selecting multiple odd or even columns/rows for dataframe为数据框选择多个奇数或偶数列/行
【发布时间】:2014-06-26 21:08:06
【问题描述】:

R 中有没有办法选择许多不连续的,即奇数或偶数行/列?

我正在为我的主成分分析绘制载荷。我有 84 行数据是这样排序的:x_1y_1x_2.....x_42y_42

目前我正在为 x 和 y 加载数据创建数据框,如下所示:

data.pc = princomp(as.matrix(data))

x.loadings <- data.frame(x=data.pc$loadings[c(1, 3, 5, 7, 9, 11, 13 ,15, 17, 19, 
21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41), 1])

yloadings <- data.frame(y=data.pc$loadings[c(2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 
22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42), 1])

肯定有更简单的方法来做到这一点?

【问题讨论】:

  • 看看?seq
  • 请注意,您说的是选择列,但您的代码从第 1 列中选择行。

标签: r dataframe pca


【解决方案1】:

当逻辑向量用于索引时,它们会被回收,所以这会得到奇数列或奇数行

 calld[ c(TRUE,FALSE), ]  # rows
 calld[ , c(TRUE,FALSE) ] #columns

偶数行或列:

 calld[ !c(TRUE,FALSE), ]  # rows
 calld[ , !c(TRUE,FALSE) ] #columns

每第三列:

  calld[ , c(TRUE,FALSE, FALSE) ]   #columns 1,4,7 , ....

最近的一位评论者声称这不再有效。我在 Ubuntu 中运行的 R 4.0.4 中没有发现:

> d <- data.frame(as.list(1:10))  # simple example construction
> d
  X1L X2L X3L X4L X5L X6L X7L X8L X9L X10L
1   1   2   3   4   5   6   7   8   9   10
> d[, c(TRUE,FALSE)]
  X1L X3L X5L X7L X9L
1   1   3   5   7   9
> d[, c(TRUE,FALSE,FALSE)]  # example: # of columns not exact multiple of length of logical vector
  X1L X4L X7L X10L
1   1   4   7   10

【讨论】:

  • 最佳答案。如果 N 在“每 N 列/行”中变大,则 c(TRUE, rep(FALSE,7)(其中 7 为 N-1)可以用作可读且简洁的替代方案。
  • 你能解释一下上面的代码吗?调用 [ !c(TRUE,FALSE), ]
  • @Standin.Wolf :不确定哪一部分让您感到困惑。这 ”!”基本上反转逻辑向量,使其真正意味着:calld[ c(FALSE,TRUE) , ]
  • in R 4.0.0 非常不幸的是,语法 `calld[ , !c(TRUE,FALSE) ]` 不再起作用了。您必须准确指定要重复的正确列数或行数。
  • @AgileBean:我刚刚在一个简单的 10 列数据框上再次测试了它,它似乎对我有用。如果您仍然看到未能遵守 R 公认的不寻常的通过隐式重复扩展向量的特性(又名“回收”),则需要发布一个反例。
【解决方案2】:

您始终可以使用 seq 生成序列:

even_indexes<-seq(2,42,2)
odd_indexes<-seq(1,41,2)

那么,

  x.loadings <- data.frame(x=data.pc$loadings[odd_indexes,1])

【讨论】:

  • 我不明白为什么关于选择奇数/偶数行或列的问题的公认答案是关于生成奇数或偶数。
【解决方案3】:

我希望使用%% 运算符为这个问题添加tidyverse 样式方法。

library(dplyr)
df <- data.frame(V1 = seq(26), V2 = letters)

df %>% filter(row_number() %% 2 == 0) ## Select even rows
df %>% filter(row_number() %% 2 == 1) ## Select odd rows
df %>% filter(row_number() %% 3 == 1) ## Select every 3rd row starting from first row

当然,您可以使用相同的想法删除每 n 行。见here

【讨论】:

    【解决方案4】:

    %%seq_len 结合使用来创建向量,用于索引您的数据框以查找偶数和奇数列/行

    试试这样的:

    even <- seq_len(ncol(data.pc)) %% 2   # index
    x.loadings <- data.frame(x=data.pc$loadings[even, ])
    y.loadings <- data.frame(x=data.pc$loadings[!even, ] )
    

    【讨论】:

      【解决方案5】:

      这里是 data.table 方法

      1. 制作一个包含列 (10) 和行 (100) 的简单 data.table

      df = data.table(sapply(1:10, rnorm, n=100))

      1. 获取偶数行/奇数行:

      甚至 df[df[, .I%%2==0]]df[seq(2,.N,2)]

      奇数 df[df[, .I%%2==1]]df[seq(1,.N,2)]

      1. 获取偶数/奇数列

      甚至 df[,.SD, .SDcols=seq(2,ncol(df),2)]

      奇数 df[,.SD, .SDcols=seq(1,ncol(df),2)]

      【讨论】:

      • 你真的可以在括号内使用.SD吗?
      • 嗯,不确定.. 你能告诉我你的意思吗?
      • @MaliRemorker 我添加了使用 .SD 来选择奇数/偶数列 - 谢谢!
      猜你喜欢
      • 1970-01-01
      • 2011-09-22
      • 2014-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多