我正在尝试完成类似此question
所示的操作但是,在我的情况下,可能会有多种情况,其中有2列的值为True:
year cat1 cat2 cat3 ... catN
2000 0 1 1 0
2001 1 0 0 0
2002 0 1 0 1
....
2018 0 1 0 0
在2000年以上的DF中,可以具有cat2和cat3类别。在这种情况下,如何创建具有第二个类别的新行。像这样:
year category
2000 cat2
2000 cat3
2001 cat1
2002 cat2
2002 catN
....
2018 cat2
答案 0 :(得分:2)
一种方法是获取所有值为1的行/列索引,从行索引的year
值子集和列索引的列名子集来创建新的数据帧。
mat <- which(df[-1] == 1, arr.ind = TRUE)
df1 <- data.frame(year = df$year[mat[, 1]], category = names(df)[-1][mat[, 2]])
df1[order(df1$year), ]
# year category
#2 2000 cat2
#5 2000 cat3
#1 2001 cat1
#3 2002 cat2
#6 2002 catN
#4 2018 cat2
数据
df <- structure(list(year = c(2000L, 2001L, 2002L, 2018L), cat1 = c(0L,
1L, 0L, 0L), cat2 = c(1L, 0L, 1L, 1L), cat3 = c(1L, 0L, 0L, 0L
), catN = c(0L, 0L, 1L, 0L)), class = "data.frame", row.names = c(NA, -4L))
答案 1 :(得分:2)
您还可以在melt
中使用reshape2
new_df = melt(df, id.vars='year')
new_df[new_df$value==1, c('year','variable')]
df = data.frame(year=c(2000,2001),
cat1=c(0,1),
cat2=c(1,0),
cat3=c(1,0))
year variable
2 2001 cat1
3 2000 cat2
5 2000 cat3
答案 2 :(得分:2)
您可以使用Tidyverse中的gather
library(tidyverse)
data = tribble(
~year,~ cat1, ~cat2, ~cat3, ~catN,
2000, 0, 1, 1, 0,
2001, 1, 0, 0 , 0,
2002, 0, 1, 0, 1
)
data %>%
gather(key = "cat", value = "bool", 2:ncol(.)) %>%
filter(bool == 1)
答案 3 :(得分:0)
这是gather
的另一种变体,其中mutate
将具有0到NA
的列,然后gather
,同时用{{ 1}}
NA
na.rm = TRUE