所以我有三列布尔值。我想产生第四列,其中包含我可能拥有的不同数据排列的标签。如果可以的话,按数字绘画。
示例:
A | B | C | newCol
------------------------
0 | 0 | 0 | 0
1 | 0 | 0 | 1
0 | 1 | 0 | 2
0 | 0 | 1 | 3
1 | 1 | 0 | 4
0 | 1 | 1 | 5
1 | 0 | 1 | 6
1 | 1 | 1 | 7
因此,根据A
,B
和C
之间发生的安排,有一个相应的标签。
最好使用tidyverse方法。
答案 0 :(得分:2)
您可以使用因数在内部被编码为整数的知识,以获得所需的结果。
首先将paste
和每一行的值放在一起。
lvls <- apply(df1[-4], 1, paste, collapse = "")
然后强迫进入"factor"
类,然后从那里进入"integer"
类。
f <- factor(lvls, levels = unique(lvls))
as.integer(f) - 1
#[1] 0 1 2 3 4 5 6
identical(df1$newCol, as.integer(f) - 1)
#[1] TRUE
数据。
df1 <- read.table(text = "
A | B | C | newCol
0 | 0 | 0 | 0
1 | 0 | 0 | 1
0 | 1 | 0 | 2
0 | 0 | 1 | 3
1 | 1 | 0 | 4
0 | 1 | 1 | 5
1 | 1 | 1 | 6
", header = TRUE, sep = "|")
答案 1 :(得分:1)
使用data.table包,我们可以保留原始排序(推荐):
library(data.table)
setDT(df1)[,new_col:=.GRP-1, by = c("A", "B","C")]
#if you want the column as factor (one-liner, no need for previous line)
setDT(df1)[,new_col:=.GRP-1, by = c("A", "B","C")][,new_col:=as.factor(new_col)]
使用dplyr,我们可以执行以下操作:
(<{> Rui的解决方案在dplyr
中实现,只需进行最小的修改即可考虑重复行的可能性):
这也保留了排序;
df1 %>% mutate(mtemp=paste0(A,B,C)) %>%
mutate(new_col = as.integer(factor(mtemp, levels = unique(.$mtemp)))-1) %>%
select(-mtemp)
我们可以使用一个虚拟变量来标记数据:
df1 %>% mutate(mtemp = paste0(A,B,C)) %>%
group_by(mtemp) %>% arrange(mtemp) %>% ungroup() %>%
mutate(new_col = c(0,cumsum(lead(mtemp)[-n()] != lag(mtemp)[-1]))) %>% select(-mtemp)
# # A tibble: 8 x 5
# A B C newCol new_col
# <dbl> <dbl> <dbl> <int> <dbl>
# 1 0 0 0 0 0
# 2 0 0 0 0 0
# 3 0 0 1 3 1
# 4 0 1 0 2 2
# 5 0 1 1 5 3
# 6 1 0 0 1 4
# 7 1 1 0 4 5
# 8 1 1 1 6 6
或参考此thread:
df1 %>%
mutate(group_id = group_indices(., paste0(A,B,C)))
关于dplyr
解决方案的说明:
第一个解决方案通过将所有三个所需变量粘贴在一起来创建虚拟变量;在下一步中,该虚拟var的每个组都会获得唯一的ID(将newCol
与new_col
比较)。基本上,如果mtemp
在任意两行之间发生变化,我们将得到True
(其数值为1
)作为我们比较的答案(lead(mtemp)...
),然后是{{1} }将其添加到先前生成的ID中,该ID最终会为不同的cumsum
(mtemp
,A
和B
的组合)生成不同的ID。此解决方案依赖于虚拟变量的排列,因此不能满足排序要求。
对于其他解决方案,只需阅读C
。
?group_indices
答案 2 :(得分:0)
如果每个唯一行的新列值不重要,则可以使用此衬纸:
df$newCol <- as.numeric(as.factor(paste(df$a, df$b, df$c, sep = "")))
如果您需要为指定的每一行唯一地将新列精确地设置为0-7,则可以使用两行代码和unique()
df$newCol <- as.factor(paste(df$a, df$b, df$c, sep = ""))
df$newCol <- as.numeric(factor(df$newCol, levels = unique(df$newCol)))-1
如果需要将此列作为要素,则只需对结果执行此操作即可:
df$newCol <- as.factor(df$newCol)