如何 select 数据框中的列范围基于它们的名称而不是它们的索引?
How to select range of columns in a dataframe based on their name and not their indexes?
在这样创建的 pandas 数据框中:
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 2 7 3 3 2 8
r1 6 9 6 7 9 1
r2 4 0 9 8 4 2
r3 9 0 4 3 5 4
r4 7 6 8 8 0 8
r5 0 6 1 8 2 2
我可以轻松地 select 某些行 and/or 使用 .loc
:
的一系列列
print df.loc[['r1', 'r5'], 'c1':'c4']
那就是 return:
c1 c2 c3 c4
r1 9 6 7 9
r5 6 1 8 2
所以,特别是 rows/columns 我可以 select 在列表中,使用冒号 rows/columns 的范围。
如何在 R 中做到这一点? Here and here 人们总是必须通过索引指定所需的列范围,但不能 - 或者至少我没有找到它 - 按名称访问这些列。举个例子:
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('r1', 'r5'),'c1':'c4']
不起作用并抛出错误。唯一对我有用的是
df[c('r1', 'r5'), 1:4]
哪个return
c1 c2 c3 c4
r1 1 2 3 4
r5 5 6 7 8
但是我如何 select 列的名称而不是索引(当我在整个分析过程中删除某些列时,这可能很重要)?在这种特殊情况下,我当然可以使用 grep
但是具有任意名称的列呢?
所以我不想用
df[c('r1', 'r5'),c('c1','c2', 'c3', 'c4')]
但实际切片。
编辑:
可以找到后续问题。
看起来你可以用 subset
:
> 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')
> 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
> subset(df, select=c1:c2)
c1 c2
r1 1 2
r2 2 3
r3 3 4
r4 4 5
r5 5 6
r6 6 7
如果你想按行名称范围进行子集化,这个技巧可以做到:
> gRI <- function(df, rName) {which(match(rNames, rName) == 1)}
> df[gRI(df,"r2"):gRI(df,"r4"),]
c1 c2 c3 c4 c5 c6
r2 2 3 4 5 6 7
r3 3 4 5 6 7 8
r4 4 5 6 7 8 9
添加到@evan058 的回答:
subset(df[rownames(df) %in% c("r3", "r4", "r5"),], select=c1:c4)
c1 c2 c3 c4
r3 3 4 5 6
r4 4 5 6 7
r5 5 6 7 8
但是请注意,:
运算符在这里可能不起作用;您将必须写出要明确包含的每一行的名称。按其他列之一的特定值分组或创建索引列(如评论中提到的 @evan058)可能更容易。
这似乎太简单了,所以我可能做错了什么。
df <- data.frame(c1=1:6, c2=2:7, c3=3:8, c4=4:9, c5=5:10, c6=6:11,
row.names=c('r1', 'r2', 'r3', 'r4', 'r5', 'r6'))
df[c('r1','r2'),c('c1','c2')]
c1 c2
r1 1 2
r2 2 3
如果您不介意使用 data.table,subset
的另一种方法是:
data.table::setDT(df)
df[1:3, c2:c4, with=F]
c2 c3 c4
1: 2 3 4
2: 3 4 5
3: 4 5 6
虽然这仍然没有解决子集行范围的问题。
使用 dplyr 包的解决方案,但您需要事先指定要select的行
rowName2Match <- c("r1", "r5")
df1 <- df %>%
select(matches("2"):matches("4")) %>%
add_rownames() %>%
mutate(idRow = match(rowname, rowName2Match)) %>%
slice(which(!is.na(idRow))) %>%
select(-idRow)
df1
> df1
Source: local data frame [2 x 4]
rowname c2 c3 c4
<chr> <int> <int> <int>
1 r1 2 3 4
2 r5 6 7 8
在这样创建的 pandas 数据框中:
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 2 7 3 3 2 8
r1 6 9 6 7 9 1
r2 4 0 9 8 4 2
r3 9 0 4 3 5 4
r4 7 6 8 8 0 8
r5 0 6 1 8 2 2
我可以轻松地 select 某些行 and/or 使用 .loc
:
print df.loc[['r1', 'r5'], 'c1':'c4']
那就是 return:
c1 c2 c3 c4
r1 9 6 7 9
r5 6 1 8 2
所以,特别是 rows/columns 我可以 select 在列表中,使用冒号 rows/columns 的范围。
如何在 R 中做到这一点? Here and here 人们总是必须通过索引指定所需的列范围,但不能 - 或者至少我没有找到它 - 按名称访问这些列。举个例子:
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('r1', 'r5'),'c1':'c4']
不起作用并抛出错误。唯一对我有用的是
df[c('r1', 'r5'), 1:4]
哪个return
c1 c2 c3 c4
r1 1 2 3 4
r5 5 6 7 8
但是我如何 select 列的名称而不是索引(当我在整个分析过程中删除某些列时,这可能很重要)?在这种特殊情况下,我当然可以使用 grep
但是具有任意名称的列呢?
所以我不想用
df[c('r1', 'r5'),c('c1','c2', 'c3', 'c4')]
但实际切片。
编辑:
可以找到后续问题
看起来你可以用 subset
:
> 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')
> 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
> subset(df, select=c1:c2)
c1 c2
r1 1 2
r2 2 3
r3 3 4
r4 4 5
r5 5 6
r6 6 7
如果你想按行名称范围进行子集化,这个技巧可以做到:
> gRI <- function(df, rName) {which(match(rNames, rName) == 1)}
> df[gRI(df,"r2"):gRI(df,"r4"),]
c1 c2 c3 c4 c5 c6
r2 2 3 4 5 6 7
r3 3 4 5 6 7 8
r4 4 5 6 7 8 9
添加到@evan058 的回答:
subset(df[rownames(df) %in% c("r3", "r4", "r5"),], select=c1:c4)
c1 c2 c3 c4
r3 3 4 5 6
r4 4 5 6 7
r5 5 6 7 8
但是请注意,:
运算符在这里可能不起作用;您将必须写出要明确包含的每一行的名称。按其他列之一的特定值分组或创建索引列(如评论中提到的 @evan058)可能更容易。
这似乎太简单了,所以我可能做错了什么。
df <- data.frame(c1=1:6, c2=2:7, c3=3:8, c4=4:9, c5=5:10, c6=6:11,
row.names=c('r1', 'r2', 'r3', 'r4', 'r5', 'r6'))
df[c('r1','r2'),c('c1','c2')]
c1 c2
r1 1 2
r2 2 3
如果您不介意使用 data.table,subset
的另一种方法是:
data.table::setDT(df)
df[1:3, c2:c4, with=F]
c2 c3 c4
1: 2 3 4
2: 3 4 5
3: 4 5 6
虽然这仍然没有解决子集行范围的问题。
使用 dplyr 包的解决方案,但您需要事先指定要select的行
rowName2Match <- c("r1", "r5")
df1 <- df %>%
select(matches("2"):matches("4")) %>%
add_rownames() %>%
mutate(idRow = match(rowname, rowName2Match)) %>%
slice(which(!is.na(idRow))) %>%
select(-idRow)
df1
> df1
Source: local data frame [2 x 4]
rowname c2 c3 c4
<chr> <int> <int> <int>
1 r1 2 3 4
2 r5 6 7 8