2017-03-18 16 views
1

私は、異なる国のいくつかの組織の活動に関する情報を含むデータフレームを持っています。コラムorgaがはorganistionは国で行っている活動の数を含む各国の列であり、は、居住地の組織の国であるC1 C4 に組織の名前が含まれています。 の値の値は、列名c1c4の数値に対応します。異なるグループの異なる列を集計します

orga <- c("AA", "AB", "AC", "BA", "BB", "BC", "BD") 
c1 <- c(3,1,0,0,2,0,1) 
c2 <- c(0,2,2,0,1,0,1) 
c3 <- c(1,0,0,1,0,2,0) 
c4 <- c(0,1,1,0,0,0,0) 
home <- c(1,2,3,2,1,3,1) 
df <- data.frame(orga, c1, c2, c3, c4, home) 

私はの列でない、団体、外国の活動のすべてについての情報を含む追加の列外国を、追加したい C4 C1に記載されたすべての活動を合計したが知っています自国。したがって、関数はすべての国の列を集計すべきではなく、自国以外の列のみを集計すべきです。

df$foreign <- c(1,2,3,1,1,0,1) 

あり:ホーム= 2が外国は次のようになります。例-場合など、

をC2を省略する場合たとえば、自宅= 1、それは、C1を除外するかどうかグループごとに列を集計し、グループごとに異なる列を残して、その合計をデータフレームに新しい列として追加する方法です。

Iはすでにdplyrパッケージの機能、ならびに塩基-Rで凝集tapplyによって基に見えたが、解決策を考え出すことができませんでした。私はあなたの助けに非常に感謝します。ありがとうございました! rowSumsを使用してそれを行うには

+0

あなたの質問に答えましたか?はいの場合は、回答を回答として選択することができます。 – bhansa

答えて

1

ここにはdplyrtidyrパッケージを使用したソリューションがあります。ここで

library(dplyr) 
library(tidyr) 

df2 <- df %>% 
    # Change the home column from number to character, 
    # Make the ID (c1, c2, c3, c4) consistent to the column names from c1 to c4 
    mutate(home = paste0("c", home)) %>% 
    # Convert the data frame from wide format to long format 
    # activity contains the columns names from c1 to c4 as labels 
    # number is the original number for each 
    gather(activity, number, -orga, -home) %>% 
    # Remove rows when home and activity number are the same 
    filter(home != activity) %>% 
    # Group by the organization 
    group_by(orga) %>% 
    # Calculate the total number of activities, call it foreign 
    summarise(foreign = sum(number)) %>% 
    # Join the results back with df by organization 
    left_join(df, by = "orga") %>% 
    # Re-organiza the column 
    select(orga, c1:home, foreign) 

は、最終的な結果です。必要な情報は、データフレームdf2foreign列にあります。

# A tibble: 7 × 7 
    orga c1 c2 c3 c4 home foreign 
    <fctr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  AA  3  0  1  0  1  1 
2  AB  1  2  0  1  2  2 
3  AC  0  2  0  1  3  3 
4  BA  0  0  1  0  2  1 
5  BB  2  1  0  0  1  1 
6  BC  0  0  2  0  3  0 
7  BD  1  1  0  0  1  1 
+0

これは私にとって最も柔軟な解決策であると思われるので、これは素晴らしいです。素敵な説明をありがとう! – uyanik

3

一つの方法、ここで

diag(as.matrix(rowSums(df[2:5])- df[2:5][df$home])) 
#[1] 1 2 3 1 1 0 1 
1

rowSumsを使用して別のオプションです。 row/columnインデックスを使用して、我々は、データセットのコピーでNAに値を交換し、その後rowSumsとし、na.rm=TRUE「ホーム」欄

df1 <- df 
df1[-1][cbind(1:nrow(df), df$home)] <- NA 
df$foreign <- rowSums(df1[2:5],na.rm=TRUE) 
df$foreign 
#[1] 1 2 3 1 1 0 1 

それともapply

を使用してを除外するために、行の合計を取得します
df$foreign <- apply(df[-1], 1, function(x) sum(head(x, -1)[-x[5]])) 
df$foreign 
#[1] 1 2 3 1 1 0 1 
関連する問題