S31*_*S31 2 r conditional-statements dataframe
所以有一种情况:
数据帧:
dat <- data.frame(colA = rep(c(0,1,0), c(6,1,8)),
colB = rep(c(1,0,1,0), c(1,4,1,9)),
colC = rep(c(0,1,0), c(9,1,5)),
colD = rep(c(0,1,0), c(8,1,6)),
colE = rep(0, 15),
color = rep(c("blue","red","yellow"), each=5),
colorId = rep(c(22,40,35), each=5))
colA colB colC colD colE color colorId
0 1 0 0 0 Blue 22
0 0 0 0 0 Blue 22
0 0 0 0 0 Blue 22
0 0 0 0 0 Blue 22
0 0 0 0 0 Blue 22
0 1 0 0 0 Red 40
1 0 0 0 0 Red 40
0 0 0 0 0 Red 40
0 0 0 1 0 Red 40
0 0 1 0 0 Red 40
0 0 0 0 0 Yellow 35
0 0 0 0 0 Yellow 35
0 0 0 0 0 Yellow 35
0 0 0 0 0 Yellow 35
0 0 0 0 0 Yellow 35
Run Code Online (Sandbox Code Playgroud)
结束目标
colNames color colorId
colB Blue 22
colB Red 40
colA Red 40
colD Red 40
colC Red 40
None Yellow 35
Run Code Online (Sandbox Code Playgroud)
这是我开始采取的方法,然后质疑自己陷入混乱.下面没有显示,我创建了另一个列,它使用rowSums(dat $ rowsu < - rowSums(dat [1:4] == 1))对'col'列的二进制值求和.
我正在考虑编写一个函数,如果有多于0个colorId重复计数,则保留rowsu> 0的所有行,如果它们全部为0且整个rowsu = 0,则保留为特殊情况下为yellow.然后在所有重复项中保留一行,类似于下面的内容.(如果是问题,在编写此部分时遇到问题)
colA colB colC colD colE color colorId
0 1 0 0 0 Blue 22
0 1 0 0 0 Red 40
1 0 0 0 0 Red 40
0 0 0 1 0 Red 40
0 0 1 0 0 Red 40
0 0 0 0 0 Yellow 35
Run Code Online (Sandbox Code Playgroud)
其次,对于后一个用名称创建列的问题,还是考虑一个if函数,如果它下面有一个1,那么使用colname名称将其提取到行名中?不确定.
使用data.table-package的可能解决方案:
library(data.table)
setDT(dat)[, .(colNames = {cs <- colSums(.SD == 1) > 0;
if(sum(cs) > 0) names(.SD)[cs] else 'None'})
, by = .(color, colorId)]
Run Code Online (Sandbox Code Playgroud)
这使:
Run Code Online (Sandbox Code Playgroud)color colorId colNames 1: blue 22 colB 2: red 40 colA 3: red 40 colB 4: red 40 colC 5: red 40 colD 6: yellow 35 None
这是做什么的:
setDT(dat)转换dat到一个"data.table"(这是一个的增强形式data.frame).data.tble-syntax的作用类似dat[i, j, by](见1b的解释).在这种情况下,dat按color和colorId( - by = .(color, colorId)部分)分组.colSums(.SD == 1) > 0检查colAto colEcolums 是否包含a 1.生成的逻辑向量暂时存储为cs..SD代表D ata的S ubset (参见上一点链接中的2b).1有sum(cs) > 0.如果是这种情况,则返回相应的列名names(.SD)[cs],如果条件不成立None则返回.使用dplyr从tidyverse你可以得到相同的结果有:
library(dplyr)
dat %>%
group_by(color, colorId) %>%
do(data.frame(colNames = {cs <- colSums(. == 1) > 0;
if(sum(cs) > 0) names(.)[cs] else 'None'}))
Run Code Online (Sandbox Code Playgroud)