使用来自两个不同列的条件重新创建数据框
Recreating a dataframe by using conditions from two different columns
我有一个庞大的数据框,看起来像这样:
df = data.frame(year = c(rep(1998,5),rep(1999,5)),
loc = c(10,rep(14,4),rep(10,2),rep(14,3)),
sitA = c(rep(0,3),1,1,0,1,0,1,1),
sitB = c(1,0,1,0,1,rep(0,4),1),
n = c(2,13,2,9,4,7,2,7,7,4))
df
year loc sitA sitB n
1 1998 10 0 1 2
2 1998 14 0 0 13
3 1998 14 0 1 2
4 1998 14 1 0 9
5 1998 14 1 1 4
6 1999 10 0 0 7
7 1999 10 1 0 2
8 1999 14 0 0 7
9 1999 14 1 0 7
10 1999 14 1 1 4
如您所见,有年份、地点、两种不同的情况(表示为 sitA
和 sitB
),最后是这些记录的计数(n
列)。
我想创建一个新的数据框,它仅反映年份和地点的计数,其中情况 A 和 B 的计数有条件地存储在列中,例如下面的所需输出:
df.new
year loc sitB.0.sitA.0 sitB.0.sitA.1 sitB.1.sitA.0 sitB.1.sitA.1
1 1998 10 0 0 2 0
2 1998 14 13 9 2 4
3 1999 10 7 2 0 0
4 1999 14 7 7 0 4
如您所知,棘手的部分是原始数据框不包含所有条件。它只有计数大于 0 的那些。因此对于原始数据帧中缺失的条件,新数据帧应该为“0”。因此,熔化(重塑)或聚合等众所周知的功能未能解决我的问题。如果能提供一点帮助,我们将不胜感激。
A tidyverse
方法,我们首先将列名附加到 sit..
列的值。然后我们 unite
并将它们组合成一列,最后 spread
值。
library(tidyverse)
df[3:4] <- lapply(names(df)[3:4], function(x) paste(x, df[, x], sep = "."))
df %>%
unite(key, sitA, sitB, sep = ".") %>%
spread(key, n, fill = 0)
# year loc sitA.0.sitB.0 sitA.0.sitB.1 sitA.1.sitB.0 sitA.1.sitB.1
#1 1998 10 0 2 0 0
#2 1998 14 13 2 9 4
#3 1999 10 7 0 2 0
#4 1999 14 7 0 7 4
如果列的位置不固定可以先用grep
cols <- grep("^sit", names(df))
df[cols] <- lapply(names(df)[cols], function(x) paste(x, df[, x], sep = "."))
我有一个庞大的数据框,看起来像这样:
df = data.frame(year = c(rep(1998,5),rep(1999,5)),
loc = c(10,rep(14,4),rep(10,2),rep(14,3)),
sitA = c(rep(0,3),1,1,0,1,0,1,1),
sitB = c(1,0,1,0,1,rep(0,4),1),
n = c(2,13,2,9,4,7,2,7,7,4))
df
year loc sitA sitB n
1 1998 10 0 1 2
2 1998 14 0 0 13
3 1998 14 0 1 2
4 1998 14 1 0 9
5 1998 14 1 1 4
6 1999 10 0 0 7
7 1999 10 1 0 2
8 1999 14 0 0 7
9 1999 14 1 0 7
10 1999 14 1 1 4
如您所见,有年份、地点、两种不同的情况(表示为 sitA
和 sitB
),最后是这些记录的计数(n
列)。
我想创建一个新的数据框,它仅反映年份和地点的计数,其中情况 A 和 B 的计数有条件地存储在列中,例如下面的所需输出:
df.new
year loc sitB.0.sitA.0 sitB.0.sitA.1 sitB.1.sitA.0 sitB.1.sitA.1
1 1998 10 0 0 2 0
2 1998 14 13 9 2 4
3 1999 10 7 2 0 0
4 1999 14 7 7 0 4
如您所知,棘手的部分是原始数据框不包含所有条件。它只有计数大于 0 的那些。因此对于原始数据帧中缺失的条件,新数据帧应该为“0”。因此,熔化(重塑)或聚合等众所周知的功能未能解决我的问题。如果能提供一点帮助,我们将不胜感激。
A tidyverse
方法,我们首先将列名附加到 sit..
列的值。然后我们 unite
并将它们组合成一列,最后 spread
值。
library(tidyverse)
df[3:4] <- lapply(names(df)[3:4], function(x) paste(x, df[, x], sep = "."))
df %>%
unite(key, sitA, sitB, sep = ".") %>%
spread(key, n, fill = 0)
# year loc sitA.0.sitB.0 sitA.0.sitB.1 sitA.1.sitB.0 sitA.1.sitB.1
#1 1998 10 0 2 0 0
#2 1998 14 13 2 9 4
#3 1999 10 7 0 2 0
#4 1999 14 7 0 7 4
如果列的位置不固定可以先用grep
cols <- grep("^sit", names(df))
df[cols] <- lapply(names(df)[cols], function(x) paste(x, df[, x], sep = "."))