/ / Как да срежете рамка от данни, като изберете диапазон от колони и редове въз основа на имена, а не индекси? - r, рамка от данни, подмножество, отрязък

Как да изрежете рамка за данни, като изберете диапазон от колони и редове, основани на имена, а не индекси? - r, dataframe, подмножество, парче

Това е последващ въпрос на въпроса, който зададох тук, Там научих а) как да направите това за колони(виж по-долу) и б) че изборът на редове и колони изглежда доста различно обработен в R, което означава, че не мога да използвам същия подход за редовете.

Да предположим, че имам рамка от данни на панди като този:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(10, size=(6, 6)),
columns=["c" + str(i) for i in range(6)],
index=["r" + str(i) for i in range(6)])

c0  c1  c2  c3  c4  c5
r0   4   2   3   9   9   0
r1   9   0   8   1   7   5
r2   2   6   7   5   4   7
r3   6   9   9   1   3   4
r4   1   1   1   3   0   3
r5   0   8   5   8   2   9

тогава мога лесно да избера редове и колони по имената им така:

print df.loc["r3":"r5", "c1":"c4"]

който се връща

    c1  c2  c3  c4
r3   9   9   1   3
r4   1   1   3   0
r5   8   5   8   2

Как бих направил това в R? Предвид подобна рамка от данни

df <- data.frame(c1=1:6, c2=2:7, c3=3:8, c4=4:9, c5=5:10, c6=6:11)
rownames(df) <- c("r1", "r2", "r3", "r4", "r5", "r6")

c1 c2 c3 c4 c5 c6
r1  1  2  3  4  5  6
r2  2  3  4  5  6  7
r3  3  4  5  6  7  8
r4  4  5  6  7  8  9
r5  5  6  7  8  9 10
r6  6  7  8  9 10 11

Очевидно, ако знам индексите на желаните от мен редове / колони, мога просто да направя:

df[3:5, 1:4]

но може да изтрия редове / колони по време на моя анализ, така че по-скоро да избера по име, отколкото по индекс. От връзката по-горе научих, че за колоните ще работи следното:

subset(df, select=c1:c4)

който се връща

  c1 c2 c3 c4
r1  1  2  3  4
r2  2  3  4  5
r3  3  4  5  6
r4  4  5  6  7
r5  5  6  7  8
r6  6  7  8  9

но как бих могъл едновременно да избера диапазон от редове по име?

В този конкретен случай, разбира се, бих могъл да използвам grep но какво ще кажете за колони, които имат произволни имена?

И аз не искам да използвам

df[c("r3", "r4" "r5"), c("c1","c2", "c3", "c4")]

а истински парче.

Отговори:

6 за отговор № 1

Можеш да използваш which() с rownames:

subset(df[which(rownames(df)=="r3"):which(rownames(df)=="r5"),], select=c1:c4)


c1 c2 c3 c4
r3  3  4  5  6
r4  4  5  6  7
r5  5  6  7  8

3 за отговор № 2

Можете да напишете функция, която ще ви даде същото поведение

"%:%" <- function(object, range) {
FUN <- if (!is.null(dim(object))) {
if (is.matrix(object)) colnames else names
} else identity
wh <- if (is.numeric(range)) range else which(FUN(object) %in% range)
FUN(object)[seq(wh[1], wh[2])]
}

df <- data.frame(c1=1:6, c2=2:7, c3=3:8, c4=4:9, c5=5:10, c6=6:11)
rownames(df) <- c("r1", "r2", "r3", "r4", "r5", "r6")

Използвайте го като

df %:% c("c2", "c4")
# [1] "c2" "c3" "c4"

rownames(df) %:% c("r2", "r4")
# [1] "r2" "r3" "r4"

За вашия въпрос

df[rownames(df) %:% c("r3", "r5"), df %:% c("c1", "c5")]
#    c1 c2 c3 c4 c5
# r3  3  4  5  6  7
# r4  4  5  6  7  8
# r5  5  6  7  8  9

2 за отговор № 3

употреба match за да намерите позицията на конкретни имена на редове.

df[match("r3", rownames(df)):match("r5", rownames(df)), match("c1", colnames(df)):match("c4", colnames(df))]

c1 c2 c3 c4
r3  3  4  5  6
r4  4  5  6  7
r5  5  6  7  8