Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何根据列的名称而不是索引来选择数据帧中的列范围?_R_Dataframe_Subset_Code Conversion - Fatal编程技术网

R 如何根据列的名称而不是索引来选择数据帧中的列范围?

R 如何根据列的名称而不是索引来选择数据帧中的列范围?,r,dataframe,subset,code-conversion,R,Dataframe,Subset,Code Conversion,在这样创建的数据框中: 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 c

在这样创建的数据框中:

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
我可以使用
.loc
轻松选择某些行和/或一系列列:

print df.loc[['r1', 'r5'], 'c1':'c4']
这将返回:

    c1  c2  c3  c4
r1   9   6   7   9
r5   6   1   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')
不工作并抛出错误。唯一对我有用的是

df[c('r1', 'r5'), 1:4]
返回

   c1 c2 c3 c4
r1  1  2  3  4
r5  5  6  7  8
但是,我如何根据列的名称而不是索引来选择列(当我在整个分析过程中删除某些列时,这可能很重要)?在这种特殊情况下,我当然可以使用
grep
,但是具有任意名称的列呢

所以我不想使用

df[c('r1', 'r5'),c('c1','c2', 'c3', 'c4')]
但实际上是一片

编辑:


可以找到一个后续问题。

看起来您可以通过
子集来完成此任务:

> 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
df行名(df)子集(df,select=c1:c4) c1 c2 c3 c4 r1 1 2 3 4 r2 2 3 4 5 r3 4 5 6 r4 5 6 7 r5 6 7 8 r6 7 8 9 >子集(df,select=c1:c2) c1 c2 r1 11 2 r2 2 3 r3 3 4 r4 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
gRI 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 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

df如果您不介意使用data.table,则可以选择
子集的另一种方法:

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包的解决方案,但您需要指定要选择的行

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
rowName2Match%
添加_rownames()%>%
变异(idRow=match(rowname,rowName2Match))%>%
切片(其中(!是.na(idRow)))%>%
选择(-idRow)
df1
>df1
来源:本地数据帧[2 x 4]
行名c2 c3 c4
1 r1 2 3 4
2 r5 6 7 8

这确实有效。现在如何同时选择行?如果您想要特定的行,那么
子集(df[c('r1','r3'),],select=c1:c4)
可以工作,但是一系列行如何(请参见我的编辑)?现在就投票,以后可能会接受,这取决于其他答案的质量……我认为标准做法是不命名行,然后使用标准索引范围对行进行子集划分。如果您需要行名称,您可以随时将它们添加为id列。这可能是一个很好的解决方法。但仍然感到奇怪的是,这不可能。请参阅我最近的编辑,了解如何进行行名称范围子集设置。我看到的大多数
R
都有
df[beginInd:endInd,]
类型行子集是的,按索引进行子集似乎更常见,但我仍然感到惊讶的是没有内置的。谢谢,但是
子集(df[c('r1','r3'),],select=c1:c4)
似乎更方便。但我实际上希望避免指定行名称。无论如何,投票结果都是上升的;)@投反对票的人:你能解释一下你为什么投反对票吗?这是一个清晰的问题,有一个最小的可重复的例子,那么问题是什么呢?感觉有点像移动门柱,专门询问关于列的问题,然后在提交答案后编辑它以包括行。最好回滚编辑并提出新问题。它们似乎非常相关,但在R数据帧中,列名和行名的处理方式截然不同。(虽然不是我的反对票,也不确定这是否是原因。)@Gregor:好吧,我对R的细节不太熟悉,在Pandas中,这是直截了当的,我可以做:
df.loc['r1':'r3','c1':'c4']
所以行和列的处理没有那么不同。如果没有更好的答案,我当然会接受提供的答案(见下面我的第一条评论),因为它确实回答了原始问题。是的,你是对的,我应该把行选择放在原始问题中,所以我理解你的否决票;谢谢你的解释!即使从一开始,我认为作为一个单独的问题会更好(但我仍然没有投反对票)。我可以为列想出三种好方法:
base::subset
如答案所示,或者
dplyr::select
data.table
。我不知道任何行名称的方法,除了黑一个。但这将是一个很好的单独问题,可能会引起一些特定的兴趣/创新的解决方案。@Gregor:好的,谢谢。如前所述,我不知道行和列的选择被如此不同地对待,我再次编辑我的问题;谢谢你让我意识到这一点。这需要指定我想要避免的行和列。PS:我没有否决,谢谢你的选择(投票结果)。行选择不是原始问题的一部分;我没想到它会与列选择有那么大的不同,所以这更像是一种奖励;)感谢您提供的替代解决方案,但似乎比@evan058的解决方案复杂得多。
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