我正在尝试根据单元格中的值提取数据框的别名。我的数据是一系列几百个类别的,在单元格中有一个简单的二进制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]])
但是,这只会返回一个类别名称!
任何帮助将不胜感激!
答案 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