问题描述
给出以下数据框(从我无法控制其内容的csv文件中读取)
C1 C2 C3 C4 C5 C6 C7 C8 C9
1 a a a c d b c c a
2 a a b b c b b a b
3 a c c d d b c b b
4 c a d c d d c d d
我需要对每一行中的每个唯一值进行计数。如果单个值出现5次或更多次,则应确定该行无效(可能通过添加其他有效/无效列)。我不在乎哪个值出现5次或更多次,只是任何值都会出现。在上面,第2行和第4行将无效。不幸的是,我不知道csv文件中将有多少行数据。
解决方法
如果您只想知道该行是否包含四个以上的条目,则可以执行以下操作:
df$invalid <- apply(df,1,function(x) max(table(x)) > 4)
#> C1 C2 C3 C4 C5 C6 C7 C8 C9 invalid
#> 1 a a a c d b c c a FALSE
#> 2 a a b b c b b a b TRUE
#> 3 a c c d d b c b b FALSE
#> 4 c a d c d d c d d TRUE
如果您实际上也想要每一行的计数,则可以执行以下操作:
cbind(df,t(apply(df[-10],function(x) table(factor(x,levels = letters[1:4])))))
#> C1 C2 C3 C4 C5 C6 C7 C8 C9 invalid a b c d
#> 1 a a a c d b c c a FALSE 4 1 3 1
#> 2 a a b b c b b a b TRUE 3 5 1 0
#> 3 a c c d d b c b b FALSE 1 3 3 2
#> 4 c a d c d d c d d TRUE 1 0 3 5
,
如果我们也将行索引用作hte列之一,我们也可以应用一次table
cbind(df,as.data.frame.matrix(table(c(row(df)),unlist(df))))
# C1 C2 C3 C4 C5 C6 C7 C8 C9 a b c d
#1 a a a c d b c c a 4 1 3 1
#2 a a b b c b b a b 3 5 1 0
#3 a c c d d b c b b 1 3 3 2
#4 c a d c d d c d d 1 0 3 5
如果我们需要创建“无效”列
t1 <- table(c(row(df)),unlist(df))
cbind(df,as.data.frame.matrix(t1),invalid = as.logical(rowSums(t1 > 4)))
# C1 C2 C3 C4 C5 C6 C7 C8 C9 a b c d invalid
#1 a a a c d b c c a 4 1 3 1 FALSE
#2 a a b b c b b a b 3 5 1 0 TRUE
#3 a c c d d b c b b 1 3 3 2 FALSE
#4 c a d c d d c d d 1 0 3 5 TRUE
数据
df <- structure(list(C1 = c("a","a","c"),C2 = c("a","c","a"),C3 = c("a","b","d"),C4 = c("c","d",C5 = c("d",C6 = c("b",C7 = c("c",C8 = c("c",C9 = c("a","d")),class = "data.frame",row.names = c("1","2","3","4"))