簡體   English   中英

按行對具有相似名稱的列求和

[英]Sum columns row-wise with similar names

我有一個dataframe ,它有很多像這樣的列:

data <- data.frame (a.1 = 1:5, a.2b = 3:7, a.5 = 5:9, bt.16 = 4:8, bt.12342 = 7:11)

我想要一個結果,其中的列對具有相同前綴的變量求和。 在這個例子中,我想返回一個 dataframe:a = (9:13), bt = (11:15)

我的真實數據集要復雜得多(我想將 web 頁面的頁面瀏覽量與不同的 utm 參數結合起來)但是針對這種情況的解決方案應該讓我走上正軌。

這里有一個基礎R的解決方案:

> prefixes = unique(sub("\\..*", "", colnames(data)))
> sapply(prefixes, function(x)rowSums(data[,startsWith(colnames(data), x)]))
      a bt
[1,]  9 11
[2,] 12 13
[3,] 15 15
[4,] 18 17
[5,] 21 19

使用基本 R 的rowsum函數的rowsum方法如何:

> t(rowsum(t(data), group = sub("\\..*", "", colnames(data))))
      a bt
[1,]  9 11
[2,] 12 13
[3,] 15 15
[4,] 18 17
[5,] 21 19

這個想法是轉置數據,使列變成行,然后應用rowsum函數來總結由相同組標簽索引的這些行。 再次轉置將數據返回到其原始形式,現在匯總具有相同標簽的列。

你可以試試

library(tidyverse)
data.frame (a.1 = 1:5, a.2b = 3:7, a.5 = 5:9, bt.16 = 4:8, bt.12342 = 7:11) %>% 
  rownames_to_column() %>% 
  gather(k, v, -rowname) %>% 
  separate(k, letters[1:2]) %>% 
  group_by(rowname, a) %>% 
  summarise(Sum=sum(v)) %>% 
  spread(a, Sum)
#> # A tibble: 5 x 3
#> # Groups:   rowname [5]
#>   rowname     a    bt
#>   <chr>   <int> <int>
#> 1 1           9    11
#> 2 2          12    13
#> 3 3          15    15
#> 4 4          18    17
#> 5 5          21    19

reprex包 (v0.2.0)於2018-04-16創建。

這是另一個tidyverse解決方案:

library(tidyverse)

t(data) %>%
  data.frame() %>%
  group_by(., id = gsub('\\..*', '', rownames(.))) %>%
  summarise_all(sum) %>%
  data.frame() %>%
  column_to_rownames(var = 'id') %>%
  t()

結果:

    a bt
X1  9 11
X2 12 13
X3 15 15
X4 18 17
X5 21 19
data <- data.frame (a.1 = 1:5, a.2b = 3:7, a.5 = 5:9, bt.16 = 4:8, bt.12342 = 7:11)
i <- grepl("a.", names(data), fixed = TRUE)
result <- data.frame(a=rowSums(data[, i]), bt=rowSums(data[, !i]))
result
# > result
#    a bt
# 1  9 11
# 2 12 13
# 3 15 15
# 4 18 17
# 5 21 19

如果您有兩個以上的前綴,您可以執行以下操作:

prefs <- c("a.", "bt.")
as.data.frame(lapply(prefs, function(p) rowSums(data[, grepl(p, names(data), fixed = TRUE)]) ))

另一種解決方案是使用矩陣乘積:

data <- data.frame (a.1 = 1:5, a.2b = 3:7, a.5 = 5:9, bt.16 = 4:8, bt.12342 = 7:11)
as.matrix(data) %*% sapply(c("a","b"), function(a,b){startsWith(b,a)}, colnames(data))

結果:

      a  b
[1,]  9 11
[2,] 12 13
[3,] 15 15
[4,] 18 17
[5,] 21 19

這里sapply(c("a","b"), function(a,b){startsWith(b,a)}, colnames(data))

         a     b
[1,]  TRUE FALSE
[2,]  TRUE FALSE
[3,]  TRUE FALSE
[4,] FALSE  TRUE
[5,] FALSE  TRUE

表示應如何組合列。 請注意,通過這種方式,您可以輕松保留數據的行名稱。

這里sapply是用來保留列名的,否則可以直接用outer(colnames(data), c("a","b"), startsWith)然后自己設置列名。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM