【发布时间】:2016-10-18 10:03:23
【问题描述】:
我有一个数据集:
data$a <- c(1,0,0,1,0)
data$b <- c(0,1,1,0,0)
data$c <- c(0,0,0,0,1)
我如何将其变成一个如下所示的分类列:
data$tranformed <- c(A,B,B,A,C)
【问题讨论】:
我有一个数据集:
data$a <- c(1,0,0,1,0)
data$b <- c(0,1,1,0,0)
data$c <- c(0,0,0,0,1)
我如何将其变成一个如下所示的分类列:
data$tranformed <- c(A,B,B,A,C)
【问题讨论】:
你可以这样做:
w <- which(data==1, arr.ind = T)
data$tranformed <- toupper(names(data)[w[order(w[,1]),2]])
# a b c tranformed
#1 1 0 0 A
#2 0 1 0 B
#3 0 1 0 B
#4 1 0 0 A
#5 0 0 1 C
最好采用这种方式,因为它适用于列名并且字母不是硬编码的。如果更改列名,您将看到相应的更改。
你甚至可以用更好的方式做到这一点:
data$tranformed <- toupper(names(data)[max.col(data)])
如果允许data 有没有任何1 的行,如下所示:
# a b c
#1 1 0 0
#2 0 1 0
#3 0 0 0
#4 1 0 0
#5 0 0 1
data <- structure(list(a = c(1, 0, 0, 1, 0), b = c(0, 1, 0, 0, 0), c = c(0,
0, 0, 0, 1)), .Names = c("a", "b", "c"), row.names = c(NA, -5L
), class = "data.frame")
你可以这样做:
inds <- which(rowSums(data)==0)
data$tranformed <- toupper(names(data)[max.col(data)])
data$tranformed[inds] <- NA
这会给你:
# a b c tranformed
#1 1 0 0 A
#2 0 1 0 B
#3 0 0 0 <NA>
#4 1 0 0 A
#5 0 0 1 C
【讨论】:
data$tranformed<-ifelse(rowSums(df)>=1,toupper(names(df)[max.col(df)]),NA)。比我的方法简单得多,做得好。
data$transformed<-factor(apply(data, 1, function(x) which(x == 1)),labels = colnames(data))
或(小写字母)
factor(LETTERS[apply(data, 1, function(x) which(x == 1))])
编辑:如果有一行只有 0,如以下示例中的第 3 行。
df=data.frame(a =c(1,0,0,1,0),
b=c(0,1,0,0,0),
c =c(0,0,0,0,1)
)
a b c
1 1 0 0
2 0 1 0
3 0 0 0
4 1 0 0
5 0 0 1
您不能使用上述解决方案,因为 apply 函数将输出长度为 0 的列表。
解决方法:
LETTERS[unlist(ifelse(sapply(apply(df, 1, function(x) which(x == 1)),length)==1,apply(df, 1, function(x) which(x == 1)),NA))]
[1] "A" "B" NA "A" "C"
【讨论】:
data.lab$drinksubcat <- factor(apply(data.lab[,35:46],1, function(x) which(x == 1)),labels = colnames(data.lab[,35:46])) Error in sort.list(y) : 'x' must be atomic for 'sort.list' Have you called 'sort' on a list? 你知道我为什么会得到这个吗?
data$LSM1 <- c(0,1,1,1,0) data$LSM2 <- c(1,0,0,0,0)一定是这个问题