在数据框上应用函数并返回数据框

时间:2018-06-21 08:40:32

标签: r dataframe

我有一个像这样的数据框

 ID  07  08  09  10  year balance

abc   0   0   0   0  09    2123.00
efg   0   0   0   0  09    780.4
xyz   0   0   0   0  07    2402.9
prq   0   0   0   0  10    123.3
mno   0   0   0   0  07    679

我需要根据“ ”列和余额中的值填写 07、08、09和10 列。 对于每个ID,对应于列年中的值的列将填充余额中的值。逐行应用。

例如,对于第一行,年份为09,因此该ID的第09列填充值为2123.00。其余年份的值始终为0。

对于第三行,由于其年值为07,所以在第07列中填充了24502.9的值。依此类推。

我的输出应该是这样

 ID  07      08  09      10    year  balance

abc   0      0  2123.00  0      09    2123.00
efg   0      0  780.4    0      09    780.4
xyz  2402.9  0   0       0      07    2402.9
prq   0      0   0      123.3   10    123.3
mno  679     0   0       0      07    679

PS:我已经为此编写了一个for循环。我需要比for循环更快的东西。我实际上正在处理数千个数据。 我不知道是否有任何类似的应用可以返回数据帧

4 个答案:

答案 0 :(得分:3)

基本上,您要做的是将数据框的右侧从长格式转换为宽格式。您可以使用spread中的tidyr函数来完成此操作。

library(tidyr)
library(dplyr)

D <- read.table(header=TRUE, text="
ID  07  08  09  10  year balance
abc  0   0   0   0  09    2123.00
efg  0   0   0   0  09    780.4
xyz  0   0   0   0  07    24502.9
prq  0   0   0   0  10    123.3
mno  0   0   0   0  07    679")

D %>%
  select(ID, year, balance) %>%
  spread(year, balance, fill=0) %>%
  bind_cols(D[,c("year","balance")])

#>    ID       7      9    10 year balance
#> 1 abc     0.0 2123.0   0.0    9  2123.0
#> 2 efg     0.0  780.4   0.0    9   780.4
#> 3 mno   679.0    0.0   0.0    7 24502.9
#> 4 prq     0.0    0.0 123.3   10   123.3
#> 5 xyz 24502.9    0.0   0.0    7   679.0

注意:输出中缺少年份08,因为示例数据中缺少年份。

答案 1 :(得分:1)

我确定你想要这个

do.call(rbind, lapply(1:nrow(df1), function(i) {
  df1[i, df1[i, 6]] <- df1[i, 7] 
  df1[i, ]
  }))

产量

   ID     07 08     09    10 year balance
1 abc    0.0  0 2123.0   0.0   09  2123.0
2 efg    0.0  0  780.4   0.0   09   780.4
3 xyz 2402.9  0    0.0   0.0   07  2402.9
4 prq    0.0  0    0.0 123.3   10   123.3
5 mno  679.0  0    0.0   0.0   07   679.0

数据

df1 <- structure(list(ID = structure(c(1L, 2L, 5L, 4L, 3L), .Label = c("abc", 
"efg", "mno", "prq", "xyz"), class = "factor"), `07` = c(0L, 
0L, 0L, 0L, 0L), `08` = c(0L, 0L, 0L, 0L, 0L), `09` = c(0L, 0L, 
0L, 0L, 0L), `10` = c(0L, 0L, 0L, 0L, 0L), year = c("09", "09", 
"07", "10", "07"), balance = c(2123, 780.4, 2402.9, 123.3, 679
)), row.names = c(NA, -5L), class = "data.frame")

答案 2 :(得分:1)

您可以使用data.tablereshape2软件包来完成此操作。

您可以使用data.frame的ID,年,余额列和dcast,其中ID为列中的行和年份,余额为值

library(reshape2) 
library(data.table) 
final_output<-dcast(setDT(df),ID~year, value.var="balance")

如果您想对列进行重新排序,可以使用以下参考资料中的代码段: Reordering dcast data frame

final_output<-dcast(setDT(df),ID~reorder(year,year), value.var="balance")

答案 3 :(得分:0)

您可以使用4行:

df$`07` <- ifelse(test = df$year=='07',yes = df$balance, no=0)
df$`08` <- ifelse(test = df$year=='08',yes = df$balance, no=0) 
df$`09` <- ifelse(test = df$year=='09',yes = df$balance, no=0)
df$`10` <- ifelse(test = df$year=='10',yes = df$balance, no=0)

与循环相比,我认为它会超快工作