R 将数据分解为每个级别并对其应用函数
我有以下数据集:R 将数据分解为每个级别并对其应用函数,r,split,dataframe,plyr,apply,R,Split,Dataframe,Plyr,Apply,我有以下数据集: name1 <- c("P1", "P2", "IndA", "IndB", "IndC", "IndD", "IndE", "IndF", "IndG") name2 <- c("P1", "P2", "IndH", "IndI", "IndJ", "IndK") name3 <- c("P1", "P2", "IndL", "IndM", "IndN") name <- c(name1, name2, name3) A <- c(1, 3,
name1 <- c("P1", "P2", "IndA", "IndB", "IndC", "IndD", "IndE", "IndF", "IndG")
name2 <- c("P1", "P2", "IndH", "IndI", "IndJ", "IndK")
name3 <- c("P1", "P2", "IndL", "IndM", "IndN")
name <- c(name1, name2, name3)
A <- c(1, 3, 1, 2, 2, 5, 5, 1, 4, 1, 3, 3, 1, 4, 3, 1, 1, 3,2,1 )
B <- c(2, 4, 3, 4, 2, 2, 6, 2, 2, 1, 4, 3, 1, 1, 5, 2,2, 1, 2, 1 )
family = c(rep(1, length (name1)), rep(2, length (name2)), rep(3, length (name3)))
mydf <- data.frame (family, name, A, B)
编辑:
预期产出:
family name A B correct
1 1 P1 1 2 FALSE
2 1 P2 3 4 FALSE
3 1 IndA 1 3 TRUE
4 1 IndB 2 4 TRUE
5 1 IndC 2 2 FALSE
6 1 IndD 5 2 FALSE
7 1 IndE 5 6 FALSE
8 1 IndF 1 2 FALSE
9 1 IndG 4 2 TRUE
10 2 P1 1 1 FALSE
11 2 P2 3 4 FALSE
12 2 IndH 3 3 FALSE
13 2 IndI 1 1 FALSE
14 2 IndJ 4 1 TRUE
15 2 IndK 3 5 FALSE
16 3 P1 1 2 TRUE
17 3 P2 1 2 TRUE
18 3 IndL 3 1 FALSE
19 3 IndM 2 2 TRUE
20 3 IndN 1 1 TRUE
仅适用于family=3(类似于其他数据集)
#仅适用于系列3的数据
name很难准确地理解您正在做什么,但是使用plyr
您希望使用一个**ply
函数,该函数接受您给定的数据类型,并返回函数返回的数据类型。在这种情况下,ddply
看起来是正确的选择
如果您在第三行中修复了函数,则会有一个mydf$B
,它应该是x$B
:
err.chk <- function (x) {
dum.match <- rbind(expand.grid(c(x[1, 2:3]), c(x[2, 2:3])),
expand.grid(c(x[2, 2:3]), c(x[1, 2:3])))
newmydf <- cbind(x, correct = paste(x$A, x$B) %in% paste(dum.match$Var1, dum.match$Var2))
return (newmydf)
}
如果运行函数前第一个块中给出的代码,则其输出与预期输出不匹配。如果在对mydf
的所有调用中仅使用df[df$family==1,],则第4行为FALSE
。尝试使用数据的子集(即仅一个族),直到函数按预期工作为止。然后,ddply
是你的答案。@对不起,贾斯汀,我的坏…我错了,索引2:3应该被3:4取代,我没有注意到添加了“家庭”列…现在结果很好,接受了你的答案。不用担心。您始终可以避免使用名称进行硬编码列标记expand.grid(x[1,c('A','B')],x[2,c('A','B')])
sorry mybad…我错了,索引2:3应该替换为3:4,我没有注意到添加了family列…现在结果很好,并接受了您的答案
require(plyr)
aaply(mydf, 1, err.chk)
family name A B correct
1 1 P1 1 2 FALSE
2 1 P2 3 4 FALSE
3 1 IndA 1 3 TRUE
4 1 IndB 2 4 TRUE
5 1 IndC 2 2 FALSE
6 1 IndD 5 2 FALSE
7 1 IndE 5 6 FALSE
8 1 IndF 1 2 FALSE
9 1 IndG 4 2 TRUE
10 2 P1 1 1 FALSE
11 2 P2 3 4 FALSE
12 2 IndH 3 3 FALSE
13 2 IndI 1 1 FALSE
14 2 IndJ 4 1 TRUE
15 2 IndK 3 5 FALSE
16 3 P1 1 2 TRUE
17 3 P2 1 2 TRUE
18 3 IndL 3 1 FALSE
19 3 IndM 2 2 TRUE
20 3 IndN 1 1 TRUE
# just data for family 3
name <- c("P1", "P2", "IndL", "IndM", "IndN")
A <- c(1, 1, 3,2,1 )
B <- c(2,2, 1, 2, 1)
mydf <- data.frame (name, A, B)
err.chk(fam3)
name A B correct
16 P1 1 2 TRUE
17 P2 1 2 TRUE
18 IndL 3 1 FALSE
19 IndM 2 2 TRUE
20 IndN 1 1 TRUE
err.chk <- function (x) {
dum.match <- rbind(expand.grid(c(x[1, 2:3]), c(x[2, 2:3])),
expand.grid(c(x[2, 2:3]), c(x[1, 2:3])))
newmydf <- cbind(x, correct = paste(x$A, x$B) %in% paste(dum.match$Var1, dum.match$Var2))
return (newmydf)
}
> ddply(mydf, .(family), err.chk)
family name A B correct
1 1 P1 1 2 FALSE
2 1 P2 3 4 FALSE
3 1 IndA 1 3 TRUE
4 1 IndB 2 4 TRUE
5 1 IndC 2 2 FALSE
6 1 IndD 5 2 FALSE
7 1 IndE 5 6 FALSE
8 1 IndF 1 2 FALSE
9 1 IndG 4 2 TRUE
10 2 P1 1 1 FALSE
11 2 P2 3 4 FALSE
12 2 IndH 3 3 FALSE
13 2 IndI 1 1 FALSE
14 2 IndJ 4 1 TRUE
15 2 IndK 3 5 FALSE
16 3 P1 1 2 TRUE
17 3 P2 1 2 TRUE
18 3 IndL 3 1 FALSE
19 3 IndM 2 2 TRUE
20 3 IndN 1 1 TRUE