R 函数或其他基本脚本,使用位于数据帧和数据帧中的id变量比较数据帧中两个变量的值

R 函数或其他基本脚本,使用位于数据帧和数据帧中的id变量比较数据帧中两个变量的值,r,dataframe,comparison,R,Dataframe,Comparison,假设您有两个数据帧,两个数据帧都包含一些但不是所有相同的记录。如果它们是相同的记录,则两个数据帧中的id变量将匹配。每个数据帧中都有一个特定变量,需要检查数据帧之间的一致性,并且需要打印任何差异: d1 <- ## first dataframe d2 <- ## second dataframe colnames(d1) #column headings for dataframe 1 [1] "id" "variable1" "variable2" "variable3" c

假设您有两个数据帧,两个数据帧都包含一些但不是所有相同的记录。如果它们是相同的记录,则两个数据帧中的id变量将匹配。每个数据帧中都有一个特定变量,需要检查数据帧之间的一致性,并且需要打印任何差异:

d1 <- ## first dataframe
d2 <- ## second dataframe

colnames(d1) #column headings for dataframe 1
[1] "id" "variable1" "variable2" "variable3"

colnames(d2) #column headings for dataframe 2 are identical
[1] "id" "variable1" "variable2" "variable3"

length(d1$id) #there are 200 records in dataframe 1
[1] 200

length(d2$id) #there are not the same number in dataframe 2
[1] 150

##Some function that takes d1$id, matches with d2$id, then compares the values of the matched, returning any discrepancies

d1这里有一个解决方案,使用随机输入数据,给定单元格在
d1
d2
之间存在差异的概率为50%:

set.seed(1);
d1 <- data.frame(id=sample(300,200),variable1=sample(2,200,replace=T),variable2=sample(2,200,replace=T),variable3=sample(2,200,replace=T));
d2 <- data.frame(id=sample(300,150),variable1=sample(2,150,replace=T),variable2=sample(2,150,replace=T),variable3=sample(2,150,replace=T));
head(d1);
##    id variable1 variable2 variable3
## 1  80         1         2         2
## 2 112         1         1         2
## 3 171         2         2         1
## 4 270         1         2         2
## 5  60         1         2         2
## 6 266         2         2         2
head(d2);
##    id variable1 variable2 variable3
## 1 258         1         2         1
## 2  11         1         1         1
## 3 290         2         1         2
## 4 222         2         1         2
## 5  81         2         1         1
## 6 200         1         2         1
com <- intersect(d1$id,d2$id); ## derive common id values
d1com <- match(com,d1$id); ## find indexes of d1 that correspond to common id values, in order of com
d2com <- match(com,d2$id); ## find indexes of d2 that correspond to common id values, in order of com
v1diff <- com[d1$variable1[d1com]!=d2$variable1[d2com]]; ## get ids of variable1 discrepancies
v1diff;
##  [1]  60 278  18 219 290  35 107   4 237 131  50 210  29 168   6 174  61 127  99 220 247 244 157  51  84 122 196 125 265 115 186 139   3 132 223 211 268 102 155 207 238  41 199 200 231 236 172 275 250 176 248 255 222  59 100  33 124
v2diff <- com[d1$variable2[d1com]!=d2$variable2[d2com]]; ## get ids of variable2 discrepancies
v2diff;
##  [1] 112  60  18 198 219 290 131  50 210  29 168 258 215 291 127 161  99 220 110 293  87 164  84 122 196 125 186 139  81 132  82  89 223 268  98  14 155 241 207 231 172  62 275 176 248 255  59 298 100  12 156
v3diff <- com[d1$variable3[d1com]!=d2$variable3[d2com]]; ## get ids of variable3 discrepancies
v3diff;
##  [1] 278 219 290  35   4 237 131 168 202 174 215 220 247 244 261 293 164  13 294  84 196 125 265 115 186  81   3  89 223 211 268  98  14 155 241 207  38 191 200 276 250  45 269 255 298 100  12 156 124
d1$variable1[match(v1diff,d1$id)]; d2$variable1[match(v1diff,d2$id)];
##  [1] 1 2 2 1 1 2 2 1 1 1 2 2 2 2 1 2 2 1 2 2 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 2 2 2 1 2 2 1 1 2 1 1 2 1 2 1 2 2 1 2 2 1 1
##  [1] 2 1 1 2 2 1 1 2 2 2 1 1 1 1 2 1 1 2 1 1 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 1 1 1 2 1 1 2 2 1 2 2 1 2 1 2 1 1 2 1 1 2 2
with(subset(d1,id%in%com&!id%in%v1diff),variable1[order(id)]); with(subset(d2,id%in%com&!id%in%v1diff),variable1[order(id)]);
##  [1] 1 1 2 1 1 1 2 2 1 2 2 1 2 2 1 1 2 1 2 1 2 1 1 1 1 1 1 2 2 2 2 1 1 1 2 2 2 1 1 1 1
##  [1] 1 1 2 1 1 1 2 2 1 2 2 1 2 2 1 1 2 1 2 1 2 1 1 1 1 1 1 2 2 2 2 1 1 1 2 2 2 1 1 1 1
这里有一个证据,证明所有不在
v1diff
中的ID的
variable1
值在
d1
d2
之间没有差异:

set.seed(1);
d1 <- data.frame(id=sample(300,200),variable1=sample(2,200,replace=T),variable2=sample(2,200,replace=T),variable3=sample(2,200,replace=T));
d2 <- data.frame(id=sample(300,150),variable1=sample(2,150,replace=T),variable2=sample(2,150,replace=T),variable3=sample(2,150,replace=T));
head(d1);
##    id variable1 variable2 variable3
## 1  80         1         2         2
## 2 112         1         1         2
## 3 171         2         2         1
## 4 270         1         2         2
## 5  60         1         2         2
## 6 266         2         2         2
head(d2);
##    id variable1 variable2 variable3
## 1 258         1         2         1
## 2  11         1         1         1
## 3 290         2         1         2
## 4 222         2         1         2
## 5  81         2         1         1
## 6 200         1         2         1
com <- intersect(d1$id,d2$id); ## derive common id values
d1com <- match(com,d1$id); ## find indexes of d1 that correspond to common id values, in order of com
d2com <- match(com,d2$id); ## find indexes of d2 that correspond to common id values, in order of com
v1diff <- com[d1$variable1[d1com]!=d2$variable1[d2com]]; ## get ids of variable1 discrepancies
v1diff;
##  [1]  60 278  18 219 290  35 107   4 237 131  50 210  29 168   6 174  61 127  99 220 247 244 157  51  84 122 196 125 265 115 186 139   3 132 223 211 268 102 155 207 238  41 199 200 231 236 172 275 250 176 248 255 222  59 100  33 124
v2diff <- com[d1$variable2[d1com]!=d2$variable2[d2com]]; ## get ids of variable2 discrepancies
v2diff;
##  [1] 112  60  18 198 219 290 131  50 210  29 168 258 215 291 127 161  99 220 110 293  87 164  84 122 196 125 186 139  81 132  82  89 223 268  98  14 155 241 207 231 172  62 275 176 248 255  59 298 100  12 156
v3diff <- com[d1$variable3[d1com]!=d2$variable3[d2com]]; ## get ids of variable3 discrepancies
v3diff;
##  [1] 278 219 290  35   4 237 131 168 202 174 215 220 247 244 261 293 164  13 294  84 196 125 265 115 186  81   3  89 223 211 268  98  14 155 241 207  38 191 200 276 250  45 269 255 298 100  12 156 124
d1$variable1[match(v1diff,d1$id)]; d2$variable1[match(v1diff,d2$id)];
##  [1] 1 2 2 1 1 2 2 1 1 1 2 2 2 2 1 2 2 1 2 2 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 2 2 2 1 2 2 1 1 2 1 1 2 1 2 1 2 2 1 2 2 1 1
##  [1] 2 1 1 2 2 1 1 2 2 2 1 1 1 1 2 1 1 2 1 1 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 1 1 1 2 1 1 2 2 1 2 2 1 2 1 2 1 1 2 1 1 2 2
with(subset(d1,id%in%com&!id%in%v1diff),variable1[order(id)]); with(subset(d2,id%in%com&!id%in%v1diff),variable1[order(id)]);
##  [1] 1 1 2 1 1 1 2 2 1 2 2 1 2 2 1 1 2 1 2 1 2 1 1 1 1 1 1 2 2 2 2 1 1 1 2 2 2 1 1 1 1
##  [1] 1 1 2 1 1 1 2 2 1 2 2 1 2 2 1 1 2 1 2 1 2 1 1 1 1 1 1 2 2 2 2 1 1 1 2 2 2 1 1 1 1
在这里,我将此解决方案包装在一个函数中,该函数返回列表中不一致id值的向量,每个组件都以其表示的变量命名:

compare <- function(d1,d2,cols=setdiff(intersect(colnames(d1),colnames(d2)),'id')) {
    com <- intersect(d1$id,d2$id);
    d1com <- match(com,d1$id);
    d2com <- match(com,d2$id);
    setNames(lapply(cols,function(col) com[d1[[col]][d1com]!=d2[[col]][d2com]]),cols);
};
compare(d1,d2);
## $variable1
##  [1]  60 278  18 219 290  35 107   4 237 131  50 210  29 168   6 174  61 127  99 220 247 244 157  51  84 122 196 125 265 115 186 139   3 132 223 211 268 102 155 207 238  41 199 200 231 236 172 275 250 176 248 255 222  59 100  33 124
##
## $variable2
##  [1] 112  60  18 198 219 290 131  50 210  29 168 258 215 291 127 161  99 220 110 293  87 164  84 122 196 125 186 139  81 132  82  89 223 268  98  14 155 241 207 231 172  62 275 176 248 255  59 298 100  12 156
##
## $variable3
##  [1] 278 219 290  35   4 237 131 168 202 174 215 220 247 244 261 293 164  13 294  84 196 125 265 115 186  81   3  89 223 211 268  98  14 155 241 207  38 191 200 276 250  45 269 255 298 100  12 156 124

compare这里有一个解决方案,使用随机输入数据,给定单元格在
d1
d2
之间存在差异的概率为50%:

set.seed(1);
d1 <- data.frame(id=sample(300,200),variable1=sample(2,200,replace=T),variable2=sample(2,200,replace=T),variable3=sample(2,200,replace=T));
d2 <- data.frame(id=sample(300,150),variable1=sample(2,150,replace=T),variable2=sample(2,150,replace=T),variable3=sample(2,150,replace=T));
head(d1);
##    id variable1 variable2 variable3
## 1  80         1         2         2
## 2 112         1         1         2
## 3 171         2         2         1
## 4 270         1         2         2
## 5  60         1         2         2
## 6 266         2         2         2
head(d2);
##    id variable1 variable2 variable3
## 1 258         1         2         1
## 2  11         1         1         1
## 3 290         2         1         2
## 4 222         2         1         2
## 5  81         2         1         1
## 6 200         1         2         1
com <- intersect(d1$id,d2$id); ## derive common id values
d1com <- match(com,d1$id); ## find indexes of d1 that correspond to common id values, in order of com
d2com <- match(com,d2$id); ## find indexes of d2 that correspond to common id values, in order of com
v1diff <- com[d1$variable1[d1com]!=d2$variable1[d2com]]; ## get ids of variable1 discrepancies
v1diff;
##  [1]  60 278  18 219 290  35 107   4 237 131  50 210  29 168   6 174  61 127  99 220 247 244 157  51  84 122 196 125 265 115 186 139   3 132 223 211 268 102 155 207 238  41 199 200 231 236 172 275 250 176 248 255 222  59 100  33 124
v2diff <- com[d1$variable2[d1com]!=d2$variable2[d2com]]; ## get ids of variable2 discrepancies
v2diff;
##  [1] 112  60  18 198 219 290 131  50 210  29 168 258 215 291 127 161  99 220 110 293  87 164  84 122 196 125 186 139  81 132  82  89 223 268  98  14 155 241 207 231 172  62 275 176 248 255  59 298 100  12 156
v3diff <- com[d1$variable3[d1com]!=d2$variable3[d2com]]; ## get ids of variable3 discrepancies
v3diff;
##  [1] 278 219 290  35   4 237 131 168 202 174 215 220 247 244 261 293 164  13 294  84 196 125 265 115 186  81   3  89 223 211 268  98  14 155 241 207  38 191 200 276 250  45 269 255 298 100  12 156 124
d1$variable1[match(v1diff,d1$id)]; d2$variable1[match(v1diff,d2$id)];
##  [1] 1 2 2 1 1 2 2 1 1 1 2 2 2 2 1 2 2 1 2 2 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 2 2 2 1 2 2 1 1 2 1 1 2 1 2 1 2 2 1 2 2 1 1
##  [1] 2 1 1 2 2 1 1 2 2 2 1 1 1 1 2 1 1 2 1 1 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 1 1 1 2 1 1 2 2 1 2 2 1 2 1 2 1 1 2 1 1 2 2
with(subset(d1,id%in%com&!id%in%v1diff),variable1[order(id)]); with(subset(d2,id%in%com&!id%in%v1diff),variable1[order(id)]);
##  [1] 1 1 2 1 1 1 2 2 1 2 2 1 2 2 1 1 2 1 2 1 2 1 1 1 1 1 1 2 2 2 2 1 1 1 2 2 2 1 1 1 1
##  [1] 1 1 2 1 1 1 2 2 1 2 2 1 2 2 1 1 2 1 2 1 2 1 1 1 1 1 1 2 2 2 2 1 1 1 2 2 2 1 1 1 1
这里有一个证据,证明所有不在
v1diff
中的ID的
variable1
值在
d1
d2
之间没有差异:

set.seed(1);
d1 <- data.frame(id=sample(300,200),variable1=sample(2,200,replace=T),variable2=sample(2,200,replace=T),variable3=sample(2,200,replace=T));
d2 <- data.frame(id=sample(300,150),variable1=sample(2,150,replace=T),variable2=sample(2,150,replace=T),variable3=sample(2,150,replace=T));
head(d1);
##    id variable1 variable2 variable3
## 1  80         1         2         2
## 2 112         1         1         2
## 3 171         2         2         1
## 4 270         1         2         2
## 5  60         1         2         2
## 6 266         2         2         2
head(d2);
##    id variable1 variable2 variable3
## 1 258         1         2         1
## 2  11         1         1         1
## 3 290         2         1         2
## 4 222         2         1         2
## 5  81         2         1         1
## 6 200         1         2         1
com <- intersect(d1$id,d2$id); ## derive common id values
d1com <- match(com,d1$id); ## find indexes of d1 that correspond to common id values, in order of com
d2com <- match(com,d2$id); ## find indexes of d2 that correspond to common id values, in order of com
v1diff <- com[d1$variable1[d1com]!=d2$variable1[d2com]]; ## get ids of variable1 discrepancies
v1diff;
##  [1]  60 278  18 219 290  35 107   4 237 131  50 210  29 168   6 174  61 127  99 220 247 244 157  51  84 122 196 125 265 115 186 139   3 132 223 211 268 102 155 207 238  41 199 200 231 236 172 275 250 176 248 255 222  59 100  33 124
v2diff <- com[d1$variable2[d1com]!=d2$variable2[d2com]]; ## get ids of variable2 discrepancies
v2diff;
##  [1] 112  60  18 198 219 290 131  50 210  29 168 258 215 291 127 161  99 220 110 293  87 164  84 122 196 125 186 139  81 132  82  89 223 268  98  14 155 241 207 231 172  62 275 176 248 255  59 298 100  12 156
v3diff <- com[d1$variable3[d1com]!=d2$variable3[d2com]]; ## get ids of variable3 discrepancies
v3diff;
##  [1] 278 219 290  35   4 237 131 168 202 174 215 220 247 244 261 293 164  13 294  84 196 125 265 115 186  81   3  89 223 211 268  98  14 155 241 207  38 191 200 276 250  45 269 255 298 100  12 156 124
d1$variable1[match(v1diff,d1$id)]; d2$variable1[match(v1diff,d2$id)];
##  [1] 1 2 2 1 1 2 2 1 1 1 2 2 2 2 1 2 2 1 2 2 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 2 2 2 1 2 2 1 1 2 1 1 2 1 2 1 2 2 1 2 2 1 1
##  [1] 2 1 1 2 2 1 1 2 2 2 1 1 1 1 2 1 1 2 1 1 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 1 1 1 2 1 1 2 2 1 2 2 1 2 1 2 1 1 2 1 1 2 2
with(subset(d1,id%in%com&!id%in%v1diff),variable1[order(id)]); with(subset(d2,id%in%com&!id%in%v1diff),variable1[order(id)]);
##  [1] 1 1 2 1 1 1 2 2 1 2 2 1 2 2 1 1 2 1 2 1 2 1 1 1 1 1 1 2 2 2 2 1 1 1 2 2 2 1 1 1 1
##  [1] 1 1 2 1 1 1 2 2 1 2 2 1 2 2 1 1 2 1 2 1 2 1 1 1 1 1 1 2 2 2 2 1 1 1 2 2 2 1 1 1 1
在这里,我将此解决方案包装在一个函数中,该函数返回列表中不一致id值的向量,每个组件都以其表示的变量命名:

compare <- function(d1,d2,cols=setdiff(intersect(colnames(d1),colnames(d2)),'id')) {
    com <- intersect(d1$id,d2$id);
    d1com <- match(com,d1$id);
    d2com <- match(com,d2$id);
    setNames(lapply(cols,function(col) com[d1[[col]][d1com]!=d2[[col]][d2com]]),cols);
};
compare(d1,d2);
## $variable1
##  [1]  60 278  18 219 290  35 107   4 237 131  50 210  29 168   6 174  61 127  99 220 247 244 157  51  84 122 196 125 265 115 186 139   3 132 223 211 268 102 155 207 238  41 199 200 231 236 172 275 250 176 248 255 222  59 100  33 124
##
## $variable2
##  [1] 112  60  18 198 219 290 131  50 210  29 168 258 215 291 127 161  99 220 110 293  87 164  84 122 196 125 186 139  81 132  82  89 223 268  98  14 155 241 207 231 172  62 275 176 248 255  59 298 100  12 156
##
## $variable3
##  [1] 278 219 290  35   4 237 131 168 202 174 215 220 247 244 261 293 164  13 294  84 196 125 265 115 186  81   3  89 223 211 268  98  14 155 241 207  38 191 200 276 250  45 269 255 298 100  12 156 124

compare这里有一种使用
merge
的方法

首先,合并数据帧,保留所有列

x <- merge(d1, d1, by="id")

下面是一种使用
merge
的方法

首先,合并数据帧,保留所有列

x <- merge(d1, d1, by="id")

你想要一个数据库连接,也许你可以使用dplyr的左连接,但你应该先给我们样本数据并以可复制的方式输出。@AlexanderOrona,小点:当沿着向量生成序列时,你应该使用
seq\u-along()
而不是
seq()
。这是因为如果输入向量恰好只包含一个元素,
seq()
会更改其行为,以生成从1到元素值的序列。因此,例如,
seq(3)
生成
123
,但您可能需要
1
。或者,可以使用
1:length(x)
,但这不能正确处理零长度向量的退化情况
seq_-along()
完美地处理了所有这些情况。如果您想要数据库连接,可能可以使用dplyr中的left_-join,但您应该首先以可复制的方式为我们提供样本数据和输出。@AlexanderOrona,小点:当沿着向量生成序列时,您应该使用
seq_-along()
而不是
seq()
。这是因为如果输入向量恰好只包含一个元素,
seq()
会更改其行为,以生成从1到元素值的序列。因此,例如,
seq(3)
生成
123
,但您可能需要
1
。或者,可以使用
1:length(x)
,但这不能正确处理零长度向量的退化情况
seq_-along()
完美地处理了所有这些情况。如果您想要数据库连接,可能可以使用dplyr中的left_-join,但您应该首先以可复制的方式为我们提供样本数据和输出。@AlexanderOrona,小点:当沿着向量生成序列时,您应该使用
seq_-along()
而不是
seq()
。这是因为如果输入向量恰好只包含一个元素,
seq()
会更改其行为,以生成从1到元素值的序列。因此,例如,
seq(3)
生成
123
,但您可能需要
1
。或者,可以使用
1:length(x)
,但这不能正确处理零长度向量的退化情况
seq_along()
完美地处理了所有这些情况。