我不知道此问题是否曾被提出过,所以我想继续发布。 我有一个如下所示的数据框:
x <- data.frame(species = c("Alpha", "Alpha", "Alpha","Beta", "Beta", "Beta","Gamma", "Gamma", "Gamma"), lifestage = factor(c("infant", "juvenile", "adult", "infant", "juvenile", "adult", "infant", "juvenile", "adult"),levels = c("infant", "juvenile", "adult")), age = c(10, 20, 30, 11, 21, 31, 9, 19, 29))
ggplot(x, aes(x = reorder(species, -age), y = age, fill = lifestage)) +
geom_bar(stat = "identity", position = position_stack(reverse = TRUE)) +
coord_flip()
等等5年的数据。每年与75列相关联,条目“C0x”与县代码下的特定“C0x”相关联。基本上它是一种付款人矩阵。
CountyCode下的所有行都是正确的(大约有65个正确的行),而垂直列并不完全正确。有非常具体的县代码(例如,1,2,3,4,6等)。
因为你可以看到C05与C05不匹配,因为它实际上并不存在,并且对角线上有一个中断。因为表格格式是为了让任何人都可以使用它,所以输入值的人显然会犯下重大错误。
唯一的目标是找到对角线上列不正确的所有值并打破对角线。我想把它们除掉。例如,在C05(列)和行C06(根据县法典)下,2012 - 2016年为零。输出可以是这样一个简单的列表:YEAR CountyCode C01 C02 C03 C04 C05 C06 . . .
2012 C01 132 0 3 1 4 9
2012 C02 0 21 0 57 0 0
2012 C03 0 0 56 0 1 1
2012 C04 0 6 0 40 0 26
2012 C06 0 0 1 0 0 0
2012 C07 0 0 1 32 219 6
. .
. .
. .
2013 C01 220 9 2 4 0 0
2013 C02 0 54 0 62 0 2
2013 C03 0 0 24 0 1 1
2013 C04 0 6 0 224 0 2
2013 C06 0 0 2 0 0 0
2013 C07 0 0 1 37 2 3
所以我可以找到这些异常值并更好地定位它们。
重点是在列中找到错误的县。
PS:每年约有65(行)x 75(列) 虽然我可以手动尝试,但我想对其进行编码以便可以进一步使用
谢谢!
答案 0 :(得分:3)
使用data.table
- 包的可能解决方案:
library(data.table)
setDT(df)
df[, .(cols_not_in_rows = setdiff(names(.SD)[-1], CountyCode),
rows_not_in_cols = setdiff(CountyCode, names(.SD)[-1]))
, by = YEAR]
给出:
YEAR cols_not_in_rows rows_not_in_cols 1: 2012 C05 C07 2: 2013 C05 C07
使用过的数据:
df <- structure(list(YEAR = c(2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 2013L, 2013L, 2013L, 2013L, 2013L, 2013L),
CountyCode = c("C01", "C02", "C03", "C04", "C06", "C07", "C01", "C02", "C03", "C04", "C06", "C07"),
C01 = c(132L, 0L, 0L, 0L, 0L, 0L, 220L, 0L, 0L, 0L, 0L, 0L),
C02 = c(0L, 21L, 0L, 6L, 0L, 0L, 9L, 54L, 0L, 6L, 0L, 0L),
C03 = c(3L, 0L, 56L, 0L, 1L, 1L, 2L, 0L, 24L, 0L, 2L, 1L),
C04 = c(1L, 57L, 0L, 40L, 0L, 32L, 4L, 62L, 0L, 224L, 0L, 37L),
C05 = c(4L, 0L, 1L, 0L, 0L, 219L, 0L, 0L, 1L, 0L, 0L, 2L),
C06 = c(9L, 0L, 1L, 26L, 0L, 6L, 0L, 2L, 1L, 2L, 0L, 3L)),
.Names = c("YEAR", "CountyCode", "C01", "C02", "C03", "C04", "C05", "C06"), class = "data.frame", row.names = c(NA, -12L))
答案 1 :(得分:2)
在基础R中,要查看哪些列不在df$CountyCode
中,您可以执行
names(df[,c(-1,-2)])[!(names(df[,c(-1,-2)]) %in% df$CountyCode)]
如果您只想保留df$CountyCode
中的列,也许您可以执行类似
library(tidyverse)
correct <- names(df[,c(-1,-2)])[names(df[,c(-1,-2)]) %in% df$CountyCode]
df %>% select(1,2, correct)
答案 2 :(得分:2)
以下是Base R解决方案:
do.call(rbind, lapply(split(df, df$YEAR), function(x){
Column = as.matrix(x[,-(1:2)])
Row = x$CountyCode
data.frame(Column = colnames(Column)[diag(Column) == 0],
Row = Row[diag(Column) == 0])
}))
<强>结果:强>
Column Row
2012 C05 C06
2013 C05 C06
数据:强>
df <- structure(list(YEAR = c(2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 2013L, 2013L, 2013L, 2013L, 2013L, 2013L),
CountyCode = c("C01", "C02", "C03", "C04", "C06", "C07", "C01", "C02", "C03", "C04", "C06", "C07"),
C01 = c(132L, 0L, 0L, 0L, 0L, 0L, 220L, 0L, 0L, 0L, 0L, 0L),
C02 = c(0L, 21L, 0L, 6L, 0L, 0L, 9L, 54L, 0L, 6L, 0L, 0L),
C03 = c(3L, 0L, 56L, 0L, 1L, 1L, 2L, 0L, 24L, 0L, 2L, 1L),
C04 = c(1L, 57L, 0L, 40L, 0L, 32L, 4L, 62L, 0L, 224L, 0L, 37L),
C05 = c(4L, 0L, 1L, 0L, 0L, 219L, 0L, 0L, 1L, 0L, 0L, 2L),
C06 = c(9L, 0L, 1L, 26L, 0L, 6L, 0L, 2L, 1L, 2L, 0L, 3L)),
.Names = c("YEAR", "CountyCode", "C01", "C02", "C03", "C04", "C05", "C06"), class = "data.frame", row.names = c(NA, -12L))