-2

我一直在努力在我的数据框中创建一些变量,如下所示:

df.1 <- data.frame(unit = c('A','B','C','A','B','C','D'),location = c(1,1,1,2,2,2,2), value.X = c('5','6', '4', '3','10', '7','3'),value.Y = c('1','4','7','9','4','6','4'),team = c('A / B', 'A / B', 'C' , 'A', 'B / C', 'B / C','D'),team.B = c('A / C ', 'A / C', 'B', 'A / B / D', 'A / B / D', 'C', 'A / B / D'),supra = c('A', 'B', 'C', 'A / C / D', 'B', 'A / C / D' , 'A / C / D'),pos.supra = c(1,2,3,1,2,1,1))

  unit location value.X value.Y  team    team.B     supra pos.supra
1    A        1       5       1 A / B    A / C          A         1
2    B        1       6       4 A / B     A / C         B         2
3    C        1       4       7     C         B         C         3
4    A        2       3       9     A A / B / D A / C / D         1
5    B        2      10       4 B / C A / B / D         B         2
6    C        2       7       6 B / C         C A / C / D         1
7    D        2       3       4     D A / B / D A / C / D         1

我需要创建一个变量,对不在value.X和不在value.Y的单位之间的差异求和。如果所讨论的单位等于一,那么它要么是第一,要么紧随其后。我在每个 中都需要这个。我知道步骤太多,所以这里有更详细的描述。也许您可以跳过或颠倒这些步骤的顺序。没关系。team.Bteamsuprapos.supra.1pos.supra.1unitlocation

(1) 找到supra排名第一或以下的队伍(如果单位有suprawithpos.supra等于1

supra.I.need = c('B','A','A','B','A / C / D', 'B','B')

(2) 检查谁who.I.need不在team但在team.B

that.is.not.in.team.but.are.in.team.B = c('NA','NA','NA','B', 'A,D','NA','B')

( 3 ) 最后,计算上面变量中所有单位之间的差value.Y并将它们相加(注意我对和的增量求和):value.XAD

delta = c('NA','NA','NA','8','2','NA','8')

因此,最终的数据框应如下所示:

df.2 <- data.frame(unit = c('A','B','C','A','B','C','D'),location = c(1,1,1,2,2,2,2), value.X = c('5','6', '4', '3','10', '7','3'),value.Y = c('1','4','7','9','4','6','4'),team = c('A / B', 'A / B', 'C' , 'A', 'B / C', 'B / C','D'),team.B = c('A / C ', 'A / C', 'B', 'A / B / D', 'A / B / D', 'C', 'A / B / D'),supra = c('A', 'B', 'C', 'A / C / D', 'B', 'A / C / D' , 'A / C / D'),pos.supra = c(1,2,3,1,2,1,1),supra.I.need = c('B','A','A','B','A / C / D', 'B','B'),that.is.not.in.team.but.are.in.team.B = c('NA','NA','NA','B', 'A,D','NA','B'),delta = c('NA','NA','NA','8','2','NA','8'))

  unit location value.X value.Y  team    team.B     supra pos.supra supra.I.need that.is.not.in.team.but.are.in.team.B delta
1    A        1       5       1 A / B    A / C          A         1            B                                    NA    NA
2    B        1       6       4 A / B     A / C         B         2            A                                    NA    NA
3    C        1       4       7     C         B         C         3            A                                    NA    NA
4    A        2       3       9     A A / B / D A / C / D         1            B                                     B     8
5    B        2      10       4 B / C A / B / D         B         2    A / C / D                                   A,D     2
6    C        2       7       6 B / C         C A / C / D         1            B                                    NA    NA
7    D        2       3       4     D A / B / D A / C / D         1            B                                     B     8

任何帮助将非常感激。

4

1 回答 1

2

这是一个尝试。其中大部分是创建变量或匹配多个结果并使用%in%. 我在最后一步陷入困境,所以循环很容易。我对代码进行了一些注释以显示我在做什么。

请注意,所有这些都通过stringsAsFactors = FALSE在 data.frame 中使用来处理字符向量。我不确定为什么您的数字向量都作为字符向量输入,但如果这不是您的实际数据集的样子,您可以避免使用as.numeric.

require(plyr)
# create the supra needed when pos.supra is 1 or not
df1 = ddply(df.1, .(location), transform,
        needed = ifelse(pos.supra == 1, supra[pos.supra == 2], supra[pos.supra == 1]) )

# break apart the teams into lists for team, team.B, needed
    # the result is a list
# strsplit needs character vectors, not factors
team = strsplit(df1$team, " / ")
teamb = strsplit(df1$team.B, " / ")
needs = strsplit(as.character(df1$needed), " / ")

# pull out everything in team b that's not in team
b.not.team = mapply(function(x, y) x[!x %in% y], teamb, team)

# now match needed supra and everything in team b but not team and
    # paste together the results with a comma between and put in df1
df1$bneeded = mapply(function(x, y) paste0(x[x %in% y], collapse = ","), needs, b.not.team)


for (i in 1:nrow(df1) ){
    matchto = unlist(strsplit(df1$bneeded[i], ","))
    diffs = as.numeric(df1$value.X[df1$unit %in% matchto]) -
        as.numeric(df1$value.Y[df1$unit %in% matchto])
    df1$delta[i] = sum(diffs)
}

df1$bneeded[df1$bneeded == ""] = NA
df1$delta[df1$delta == 0] = NA
df1

** 编辑 for 循环替代方案 ** 这是用于创建 x 和 y 之间差异的循环替代方案。有时,您只需要一个新的早晨来了解代码中的问题。;) 我喜欢在许多情况下使用循环,因为它可以很容易地阅读代码中发生的事情。在这种情况下,我mapply在其余代码中都使用了,所以这里是mapply选项。

df1$diffxy = mapply(function(x, y) sum(as.numeric(df1$value.X[x %in% y])) - 
                    sum(as.numeric(df1$value.Y[x %in% y])),
      df1["unit"], strsplit(df1$bneeded, ","))
于 2013-10-09T02:14:17.153 回答