根据条件在数据框中交换行

时间:2015-11-06 19:25:41

标签: r dataframe data.table swap reshape

我有一个data.table这样的东西。这是dput

structure(list(Sepal.Length = c(5.4, 5.1, 5, 5, 4.9, 4.9, 4.7, 
4.6, 4.6, 4.4, 5.4, 5.1, 5, 5, 4.9, 4.9, 4.7, 4.6, 4.6, 4.4), 
    Sepal.Width = c(3.9, 3.5, 3.6, 3.4, 3.1, 3, 3.2, 3.4, 3.1, 
    2.9, 3.9, 3.5, 3.6, 3.4, 3.1, 3, 3.2, 3.4, 3.1, 2.9), Petal.Length = c(1.7, 
    1.4, 1.4, 1.5, 1.5, 1.4, 1.3, 1.4, 1.5, 1.4, 1.7, 1.4, 1.4, 
    1.5, 1.5, 1.4, 1.3, 1.4, 1.5, 1.4), Petal.Width = c(0.4, 
    0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.2, 0.2, 0.4, 0.2, 0.2, 
    0.2, 0.1, 0.2, 0.2, 0.3, 0.2, 0.2), Species = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L), .Label = c("setosa", "versicolor", "virginica"
    ), class = "factor"), order = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 
    8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L)), .Names = c("Sepal.Length", 
"Sepal.Width", "Petal.Length", "Petal.Width", "Species", "order"
), row.names = c(NA, -20L), class = c("data.table", "data.frame"
), .internal.selfref = <pointer: 0x0000000000340788>)

看起来像这样。这只是一个样本。

    Sepal.Length Sepal.Width Petal.Length Petal.Width Species order
 1:          5.4         3.9          1.7         0.4  setosa     1
 2:          5.1         3.5          1.4         0.2  setosa     2
 3:          5.0         3.6          1.4         0.2  setosa     3
 4:          5.0         3.4          1.5         0.2  setosa     4
 5:          4.9         3.1          1.5         0.1  setosa     5
 6:          4.9         3.0          1.4         0.2  setosa     6
 7:          4.7         3.2          1.3         0.2  setosa     7
 8:          4.6         3.4          1.4         0.3  setosa     8
 9:          4.6         3.1          1.5         0.2  setosa     9
10:          4.4         2.9          1.4         0.2  setosa    10
11:          5.4         3.9          1.7         0.4  setosa     1
12:          5.1         3.5          1.4         0.2  setosa     2
13:          5.0         3.6          1.4         0.2  setosa     3
14:          5.0         3.4          1.5         0.2  setosa     4
15:          4.9         3.1          1.5         0.1  setosa     5
16:          4.9         3.0          1.4         0.2  setosa     6
17:          4.7         3.2          1.3         0.2  setosa     7
18:          4.6         3.4          1.4         0.3  setosa     8
19:          4.6         3.1          1.5         0.2  setosa     9
20:          4.4         2.9          1.4         0.2  setosa    10

我想要的是在列order的值为1和2的地方交换这些行(保持列order不变,但交换剩余的列)。 因此,在上表中,第1行将与第2行交换,第11行将与第12行交换。

所以输出看起来像:

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species order
 1:          5.1         3.5          1.4         0.2  setosa     1
 2:          5.4         3.9          1.7         0.4  setosa     2
 3:          5.0         3.6          1.4         0.2  setosa     3
 4:          5.0         3.4          1.5         0.2  setosa     4
 5:          4.9         3.1          1.5         0.1  setosa     5
 6:          4.9         3.0          1.4         0.2  setosa     6
 7:          4.7         3.2          1.3         0.2  setosa     7
 8:          4.6         3.4          1.4         0.3  setosa     8
 9:          4.6         3.1          1.5         0.2  setosa     9
10:          4.4         2.9          1.4         0.2  setosa    10
11:          5.1         3.5          1.4         0.2  setosa     1
12:          5.4         3.9          1.7         0.4  setosa     2
13:          5.0         3.6          1.4         0.2  setosa     3
14:          5.0         3.4          1.5         0.2  setosa     4
15:          4.9         3.1          1.5         0.1  setosa     5
16:          4.9         3.0          1.4         0.2  setosa     6
17:          4.7         3.2          1.3         0.2  setosa     7
18:          4.6         3.4          1.4         0.3  setosa     8
19:          4.6         3.1          1.5         0.2  setosa     9
20:          4.4         2.9          1.4         0.2  setosa    10
> 

请注意在上面的输出行1和2中,原始表的第11行和第12行已经交换,保持列order不变。如何以最有效的方式执行此操作,即快速运行而不运行任何循环?

1 个答案:

答案 0 :(得分:1)

由于您要交换数据,因此必须在执行交换之前创建副本。在下面的代码中,我创建了一个df1 data.frame,一个df的副本。在将它们插入原始df之前,我用它来获取正确的行。我只选择前五列来保持df $ order完好无损。

df <-structure(list(Sepal.Length = c(5.4, 5.1, 5, 5, 4.9, 4.9, 4.7,
4.6, 4.6, 4.4, 5.4, 5.1, 5, 5, 4.9, 4.9, 4.7, 4.6, 4.6, 4.4),
    Sepal.Width = c(3.9, 3.5, 3.6, 3.4, 3.1, 3, 3.2, 3.4, 3.1,
    2.9, 3.9, 3.5, 3.6, 3.4, 3.1, 3, 3.2, 3.4, 3.1, 2.9), Petal.Length = c(1.7,
    1.4, 1.4, 1.5, 1.5, 1.4, 1.3, 1.4, 1.5, 1.4, 1.7, 1.4, 1.4,
    1.5, 1.5, 1.4, 1.3, 1.4, 1.5, 1.4), Petal.Width = c(0.4,
    0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.2, 0.2, 0.4, 0.2, 0.2,
    0.2, 0.1, 0.2, 0.2, 0.3, 0.2, 0.2), Species = structure(c(1L,
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
    1L, 1L, 1L, 1L), .Label = c("setosa", "versicolor", "virginica"
    ), class = "factor"), order = c(1L, 2L, 3L, 4L, 5L, 6L, 7L,
    8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L)), .Names = c("Sepal.Length",
"Sepal.Width", "Petal.Length", "Petal.Width", "Species", "order"
), row.names = c(NA, -20L), class = c("data.table", "data.frame"
))
df1 <-df

df[df$order==2,1:5] <-df1[df1$order==1,1:5]
df[df$order==1,1:5] <-df1[df1$order==2,1:5]
> df
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species order
1           5.1         3.5          1.4         0.2  setosa     1
2           5.4         3.9          1.7         0.4  setosa     2
3           5.0         3.6          1.4         0.2  setosa     3
4           5.0         3.4          1.5         0.2  setosa     4
5           4.9         3.1          1.5         0.1  setosa     5
6           4.9         3.0          1.4         0.2  setosa     6
7           4.7         3.2          1.3         0.2  setosa     7
8           4.6         3.4          1.4         0.3  setosa     8
9           4.6         3.1          1.5         0.2  setosa     9
10          4.4         2.9          1.4         0.2  setosa    10
11          5.1         3.5          1.4         0.2  setosa     1
12          5.4         3.9          1.7         0.4  setosa     2
13          5.0         3.6          1.4         0.2  setosa     3
14          5.0         3.4          1.5         0.2  setosa     4
15          4.9         3.1          1.5         0.1  setosa     5
16          4.9         3.0          1.4         0.2  setosa     6
17          4.7         3.2          1.3         0.2  setosa     7
18          4.6         3.4          1.4         0.3  setosa     8
19          4.6         3.1          1.5         0.2  setosa     9
20          4.4         2.9          1.4         0.2  setosa    10