[英]How to remove duplicated rows based on 3 columns for only one factor level?
[英]Remove duplicated rows dependend on factor
我想從由不同的fators和條件分層的數據幀中刪除重復的行,例如最高均值或sd。
一些數據, a
是行的因子和id。
set.seed(13654)
a<- sort(c(1,1,4,1,2,3,2,3,1,5))
b<- matrix(runif(100,min = 6,max = 14),nrow = 10)
c<- data.frame(a,b)
例如,我想減少具有最高平均值的行上的最終數據集。
# calculate means per row
gr <- cbind(a,M=rowMeans(c[,-1]))
# get rows stratified by a with highest mean:
gr1 <- aggregate(M~a,gr,which.max)
gr1
a M
1 1 3
2 2 2
3 3 1
4 4 1
5 5 1
因此,因子級別1的第三行,因子級別2的第二行......應該包括在新數據幀中。 我想避免循環。 我嘗試的是split
數據然后使用lapply
,但到目前為止沒有工作。
cl <- split(c,a)
# this function does not work it will select not the correct rows.
lapply(cl, "[", gr1, )
我的最終目標是這樣的功能:
remove.dupl <- function(data,factor,method=c(highest.mean,highest.sd,lowest.sd,...))
你能為我的問題提供一些tipps或解決方案嗎? 按照我的工作流程,我需要一個“操作方法”,使用"["
正確使用lapply從數據框列表中選擇不同的行。
嘗試使用by()
函數:
set.seed(13654)
a <- sort(c(1,1,4,1,2,3,2,3,1,5))
b <- matrix(runif(100,min = 6,max = 14),nrow = 10)
c <- data.frame(a,b)
myfun <- function(x) which.max(rowMeans(x)) # just replicating your example, you could define other functions here
d <- by(data = c, INDICES = c$a, function(x) x[myfun(x), ]) # use by() to select rows, based on myfun()
d <- do.call(rbind, d) # turn result of by() function into a data frame
使用data.table包,我會按如下方式處理:
library(data.table)
# method 1:
setDT(cc)[, `:=` (rn = 1:.N, wm = which.max(rowMeans(.SD))), a][rn==wm]
# method 2:
setDT(cc)[, wm := frank(1/rowMeans(.SD), ties.method="first"), a][wm==1]
這使:
a X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 wm rn
1: 1 13.946254 7.302729 9.406389 8.924367 8.129423 10.174735 6.547805 11.618872 12.84100 9.494790 3 3
2: 2 13.606555 12.798149 11.261258 12.991822 12.875935 11.199411 8.551149 10.377451 13.63219 13.643163 2 2
3: 3 6.820769 13.748507 11.630297 11.559873 6.196406 8.925419 11.230415 10.584249 10.41442 6.821673 1 1
4: 4 8.418767 10.673998 6.693021 11.101287 7.855519 9.106210 12.279536 6.925023 6.92334 10.279204 1 1
5: 5 11.529072 7.940031 10.746172 8.535466 13.703122 12.294424 11.362498 11.256843 13.95535 13.264835 1 1
在基地R你可以做:
cc$rm <- apply(cc[,-1], 1, mean)
cc$wm <- ave(cc$rm, cc$a, FUN = function(x) max(x)==x)
cc[cc$wm == 1,]
這使:
a X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 rm wm
3 1 13.946254 7.302729 9.406389 8.924367 8.129423 10.174735 6.547805 11.618872 12.84100 9.494790 9.838637 1
6 2 13.606555 12.798149 11.261258 12.991822 12.875935 11.199411 8.551149 10.377451 13.63219 13.643163 12.093708 1
7 3 6.820769 13.748507 11.630297 11.559873 6.196406 8.925419 11.230415 10.584249 10.41442 6.821673 9.793203 1
9 4 8.418767 10.673998 6.693021 11.101287 7.855519 9.106210 12.279536 6.925023 6.92334 10.279204 9.025591 1
10 5 11.529072 7.940031 10.746172 8.535466 13.703122 12.294424 11.362498 11.256843 13.95535 13.264835 11.458781 1
回復你的評論:作為替代方案,你可以在ave
使用rank
函數:
# duplicate the row for which 'max(x)==x' for the first group
cc <- rbind(cc,cc[3,])
cc$wm2 <- ave(cc$rm, cc$a, FUN = function(x) rank(-x, ties.method = "first"))
cc[cc$wm2 == 1,]
這使:
a X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 rm wm wm2
3 1 13.946254 7.302729 9.406389 8.924367 8.129423 10.174735 6.547805 11.618872 12.84100 9.494790 9.838637 1 1
6 2 13.606555 12.798149 11.261258 12.991822 12.875935 11.199411 8.551149 10.377451 13.63219 13.643163 12.093708 1 1
7 3 6.820769 13.748507 11.630297 11.559873 6.196406 8.925419 11.230415 10.584249 10.41442 6.821673 9.793203 1 1
9 4 8.418767 10.673998 6.693021 11.101287 7.855519 9.106210 12.279536 6.925023 6.92334 10.279204 9.025591 1 1
10 5 11.529072 7.940031 10.746172 8.535466 13.703122 12.294424 11.362498 11.256843 13.95535 13.264835 11.458781 1 1
注意:我將數據框重命名為cc
,因為最好不要使用函數名作為數據框的名稱
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.