通过使用来自两个不同列的条件来重新创建数据框

时间:2019-04-29 14:23:12

标签: r dataframe conditional

我有一个庞大的数据框,看起来像这样:

println "bash -c \'echo print\\(\\\"this is a sample text.\\\"\\) | python\'".execute().txt

如您所见,存在着年,地点,两种不同的情况(分别表示为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)。

我想创建一个新的数据框,以仅反映年份和地点的计数,其中情况A和B的计数有条件地存储在列中,例如下面的期望输出:

n

您可能意识到的棘手部分是原始数据帧未包含所有条件。它仅具有计数大于0的那些。因此,对于原始数据帧中缺少的条件,新数据帧应具有“ 0”。因此,众所周知的功能(例如熔化(重塑)或聚合)无法解决我的问题。会有所帮助。

1 个答案:

答案 0 :(得分:3)

一种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 = "."))