我有一個數據幀,其中一些連續的列具有相同的名稱。我需要搜索這些,爲每行添加它們的值,刪除一列並用其總和替換另一列。 而不預先知道哪些模式是重複的,可能必須將一個列名與以下內容進行比較以查看是否存在匹配。如何搜索具有相同名稱的列,添加列值並用相同名稱替換這些列的總和?使用R
有人可以幫忙嗎?
在此先感謝。
我有一個數據幀,其中一些連續的列具有相同的名稱。我需要搜索這些,爲每行添加它們的值,刪除一列並用其總和替換另一列。 而不預先知道哪些模式是重複的,可能必須將一個列名與以下內容進行比較以查看是否存在匹配。如何搜索具有相同名稱的列,添加列值並用相同名稱替換這些列的總和?使用R
有人可以幫忙嗎?
在此先感謝。
一些示例數據。
dfr <- data.frame(
foo = rnorm(20),
bar = 1:20,
bar = runif(20),
check.names = FALSE
)
方法:遍歷唯一的列名;如果只有其中一個名稱,那麼選擇所有具有該nme的列將返回一個向量,但是如果有重複,它也將是一個數據幀。使用rowSums
對行進行求和。 ( Duh。編輯:不像以前想象的那樣'duh')編輯:lapply
返回一個列表,我們需要將它改寫成數據框,最後我們修復這些名稱。sapply
避免了最後一步的需要。
unique_col_names <- unique(colnames(dfr))
new_dfr <- sapply(unique_col_names, function(name)
{
subs <- dfr[, colnames(dfr) == name]
if(is.data.frame(subs))
rowSums(subs)
else
subs
})
> dfrm <- data.frame(a = 1:10, b= 1:10, cc= 1:10, dd=1:10, ee=1:10)
> names(dfrm) <- c("a", "a", "b", "b", "b")
> sapply(unique(names(dfrm)[duplicated(names(dfrm))]),
function(x) Reduce("+", dfrm[ , grep(x, names(dfrm))]))
a b
[1,] 2 3
[2,] 4 6
[3,] 6 9
[4,] 8 12
[5,] 10 15
[6,] 12 18
[7,] 14 21
[8,] 16 24
[9,] 18 27
[10,] 20 30
編輯2:使用rowSums允許第一sapply argumentto只是unique(names(dfrm))
的簡化,在需要記住的費用,包括降= FALSE在 「[」:
sapply(unique(names(dfrm)),
function(x) rowSums(dfrm[ , grep(x, names(dfrm)), drop=FALSE]))
爲了應對與NA的:
sapply(unique(names(dfrm)),
function(x) apply(dfrm[grep(x, names(dfrm))], 1,
function(y) if (all(is.na(y))) {NA} else { sum(y, na.rm=TRUE) }
) )
(編輯說明:解決湯米反例 - 把獨特的周圍名稱(。)[。]構建。 的錯誤碼是:
sapply(names(dfrm)[unique(duplicated(names(dfrm)))],
function(x) Reduce("+", dfrm[ , grep(x, names(dfrm))]))
不適用於'dfrm = data.frame(a = 1:10,b = 20:29,a = 101:110,b = 200:209,a = 1001:1010,check.names = F)' – Tommy 2011-05-09 15:21:20
@Tommy。謝謝。指出我應該包裝獨特的名稱(dfrm)[重複....]固定。 – 2011-05-09 15:37:43
+1可愛的使用'減少'。 – 2011-05-09 15:50:50
的一種方式是使用(驚奇)的duplicated
函數,然後通過循環它們來計算總和,以確定重複值。這裏有一個例子:
dat.dup <- data.frame(x=1:10, x=1:10, x=1:10, y=1:10, y=1:10, z=1:10, check.names=FALSE)
dups <- unique(names(dat.dup)[duplicated(names(dat.dup))])
for (i in dups) {
dat.dup[[i]] <- rowSums(dat.dup[names(dat.dup) == i])
}
dat <- dat.dup[!duplicated(names(dat.dup))]
謝謝,這是我原來的想法,但我沒有編碼。而且我也不熟悉「獨特」。 – Assu 2011-05-09 17:11:24
這是我的一個班輪
# transpose data frame, sum by group = rowname, transpose back.
t(rowsum(t(dfrm), group = rownames(t(dfrm))))
關於 '咄':rowSums確實求和行,但rowsum求和列;-) – Tommy 2011-05-09 15:15:52
@Tommy:採取點。 – 2011-05-09 15:47:10
感謝您的回覆。我曾與rowSums「杜」工作,這不是我的問題的主要問題!另外,如果我可以這樣說的話,我認爲「Duh」不適合在本論壇上發佈!;) – Assu 2011-05-09 15:51:04