R:根据行和列组合创建新列

时间:2016-12-12 16:39:20

标签: r

我确信这可能很简单,但我无法找到解决方案..我有多年的缓冲系列。在每个缓冲区中,我记录森林覆盖的范围。森林覆盖率多年来下降。在每个缓冲区中,我也有一种管理方式。

我想在我的数据集中添加两个新列: 关于2003年管理类型0和1的原始森林范围的问题。第二个关于森林范围与原始森林范围的关系,从2003年开始,用于两种管理类型。

基于这些答案,我会假设使用类似的东西: R: fill new columns in data.frame based on row values by condition?

df$area2003<-with(df, area[year == 2003 & manag == 0][match(buff, buff[year== 2003 & manag == 0])])

但是它没有预期的效果。

我的例子:

# create data frame
buff<-c(c(rep(c(1:2), each = 2)), 
            c(rep(c(1:2), each = 2)))
area<-seq(800, 1, by = -100) 
year<-rep(2003:2004, each = 4)
manag<-rep(0:1, 4)

# create data frame
df<-data.frame(buff, area, year, manag)

# create values for original forest extent - how to code this???
df$area2003<-with(df, area[year == 2003 & manag == 0][match(distance, distance[year== 2003 & manag == 0])])
df$area2003<-with(df, area[year == 2003 & manag ==1 ][match(distance, distance[year== 2003 & manag == 1])])

# calculate forest rate:
df$rate<-df$area * 100/ df$area2003

我期望得到什么:

  buff area year manag area2003   rate
1    1  800 2003     0      800 100.00
2    1  700 2003     1      700 100.00
3    2  600 2003     0      600 100.00
4    2  500 2003     1      500 100.00
5    1  400 2004     0      800  50.00
6    1  300 2004     1      700  42.86
7    2  200 2004     0      600  33.34
8    2  100 2004     1      500  20.00

2 个答案:

答案 0 :(得分:1)

在这种情况下,由于您没有尝试更新现有变量,因此最好使用旧式merge

dfNew <- merge(df, setNames(df[df$year == 2003, c("buff",  "manag", "area")],
                            c("buff",  "manag", "area2003")),
               by=c("buff",  "manag"))

# calculate change
dfNew$rate <- with(dfNew, 1 - abs(area - area2003) / area2003) * 100

返回

dfNew
  buff manag area year area2003      rate
1    1     0  800 2003      800 100.00000
2    1     0  400 2004      800  50.00000
3    1     1  700 2003      700 100.00000
4    1     1  300 2004      700  42.85714
5    2     0  600 2003      600 100.00000
6    2     0  200 2004      600  33.33333
7    2     1  500 2003      500 100.00000
8    2     1  100 2004      500  20.00000

在第一行中,我结合了许多步骤,将数据框的子集分配到2003和感兴趣的列,并使用setNames在这个子集data.frame中展示变量。

要按照您的要求订购data.frame,请使用

dfNew <- dfNew[with(dfNew, order(year, buff, manag)), ]

合并可以扩展到其他行。例如,

dfNew <- merge(df, df[df$year == 2003, c("buff",  "manag", "area")],
               by=c("buff",  "manag"))

names(dfNew) <- c("buff",  "manag", "area", "year", "area2003")

答案 1 :(得分:1)

saveOptions()function saveOptions(e) { e.preventDefault(); browser.storage.local.set({ color: document.querySelector("#color").value }); } )的窗口函数最适合这种转换。 this vignette中的更多示例。

dplyr