我有一个像这样的数据框
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循环更快的东西。我实际上正在处理数千个数据。 我不知道是否有任何类似的应用可以返回数据帧
答案 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.table
和reshape2
软件包来完成此操作。
您可以使用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)
与循环相比,我认为它会超快工作