R:如何检索数据框的列名

时间:2018-07-31 12:39:52

标签: r dataframe which

我正在尝试根据单元格中的值提取数据框的别名。我的数据是一系列几百个类别的,在单元格中有一个简单的二进制0或1,以指示我要在新df中使用的列名。

为了说明我的观点:

year cat1 cat2 cat3 ... catN
2000  0    0    1        0
2001  1    0    0        0
2002  0    0    0        1
....
2018  0    1    0        0

我正在尝试获得类似df的文件:

year category 
2000  cat3
2001  cat1  
2002  catN  
....
2018  cat2  

我的代码:

newdf <- as.data.frame(colnames(mydf)[which(mydf == "1", arr.ind = TRUE)[2]])

但是,这只会返回一个类别名称!

任何帮助将不胜感激!

6 个答案:

答案 0 :(得分:4)

基本的R解决方案:

使用sapply查找其中的一个并获取名称。

out <- data.frame(year = df1$year, category = names(sapply(df1[, -1], function(x) which(x == 1))))

out
 year category
1 2000     cat1
2 2001     cat2
3 2002     cat3
4 2018     catN

数据:

df1 <- structure(list(year = c(2000L, 2001L, 2002L, 2018L), cat1 = c(0L, 
1L, 0L, 0L), cat2 = c(0L, 0L, 0L, 1L), cat3 = c(1L, 0L, 0L, 0L
), catN = c(0L, 0L, 1L, 0L)), class = "data.frame", row.names = c(NA, 
-4L))

答案 1 :(得分:3)

可能的解决方法是:

library(tidyverse)

df = data.frame(year = 2000:2002,
                cat1 = c(0,0,1),
                cat2 = c(1,0,0),
                cat3 = c(0,1,0))

df %>%
  gather(category, value, -year) %>%  # reshape data
  filter(value == 1) %>%              # keep rows with 1s
  select(-value) %>%                  # remove that column
  arrange(year)                       # order that column (if needed)

#   year category
# 1 2000     cat2
# 2 2001     cat3
# 3 2002     cat1

答案 2 :(得分:3)

使用max.col中的base R的另一个选项

data.frame(year = dat$year, category = names(dat[-1])[max.col(dat[-1])])
#  year category
#1 2000     cat3
#2 2001     cat1
#3 2002     catN
#4 2018     cat2

max.col查找数据中1的位置(不包括第一列),并返回一个列位置的矢量,我们使用该向量对列名称进行子集化,再次排除第一列。 / p>

Rui Barradas提供的数据。

答案 3 :(得分:1)

一个简单的解决方案:

# your data
data <-data.frame(year =c(2016,2017,2018),
                  cat.1=c(0,1,0),
                  cat.2=c(0,0,1),
                  cat.3 =c(1,0,0))

# a nice library 
library(reshape2)

# from wide to long
filtered <- melt(data, id = 'year') %>% filter(value>0) 

# remove the useless column
filtered <- filtered[,1:2]
    > filtered
  year variable
1 2017    cat.1
2 2018    cat.2
3 2016    cat.3

答案 4 :(得分:1)

这基本上是Reshaping data.frame from wide to long format的把戏。为此,我将使用软件包reshape2

然后用value == 1选择行。

result <- reshape2::melt(dat, id.vars = "year")
result <- result[result$value == 1, 1:2]
result <- result[order(result[[1]]), ]
names(result)[2] <- "category"
row.names(result) <- NULL

result
#  year category
#1 2000     cat3
#2 2001     cat1
#3 2002     catN
#4 2018     cat2

数据。

dat <- read.table(text = "
year cat1 cat2 cat3  catN
2000  0    0    1   0
2001  1    0    0   0
2002  0    0    0   1
2018  0    1    0   0
", header = TRUE)

答案 5 :(得分:1)

还使用stack

subset(data.frame(year = df$year, stack(df, select = -year)), values == 1)[-2]
#   year  ind
#2  2001 cat1
#8  2018 cat2
#9  2000 cat3
#15 2002 catN