我的数据看起来像这样
[[1897, 135, 130, 127, 70, 162, 445, 656, 608, 1019], [1897, 364, 56, 1236, 181, 172, 449, 48, 15, 18], [1897, 163, 11, 70, 166, 345, 480, 9, 60, 351]]
我想添加ID A_w B_w C_w A_b B_b C_b
1 3 4 6 0.5 0.2 0.9
2 6 5 7 1.4 3.2 7.6
3 12 11 27 5.4 3.2 6.1
等新列(A_c = A_w - A_b
和B_c
相同)。最简单的方法可能是写一个循环,但我想知道是否可以使用C_c
或apply
来完成。如您所见,变量名称具有模式。此外,它始终是lapply
和dataframe[, x]
之间的差异。
作为R的新手,我发现R文档不是很有帮助。例如,如果我没有意外地看到dataframe[, x+3]
用于表示.SD
中的子集,我将永远不知道它的存在,因为它没有在R文档或任何其他在线提及教程。实际上,堆栈溢出是我看到人们询问lapply
的唯一地方。任何处理此类情况的建议都将受到赞赏!
答案 0 :(得分:2)
基于R的想法,使用sapply
对唯一名称(_
之前)。然后使用Reduce
减去与唯一名称匹配的列,即
m1 <- sapply(unique(sub('_.*', '', names(df[-1]))), function(i)
Reduce(`-`, df[grepl(i, names(df))]))
#tidy and bind with original df,
cbind(df, setNames(data.frame(m1), paste0(colnames(m1), '_c')))
或者避免cbind
并按照@lmo建议直接进行,
baseNames <- unique(sub('_.*', '', names(df[-1])))
df[paste(baseNames, "c", sep="_")] <- sapply(baseNames, function(i)
Reduce(`-`, df[grepl(i, names(df))]))
矢量化解决方案
既然你提到另外,它始终是dataframe [,x]和dataframe [,x + 3] 之间的差异,那么完全向量化的方式就是(保持baseNames
从之前),
m1 <- matrix(seq(ncol(df)-1)+1, ncol = 2)
df[paste(baseNames, "c", sep="_")] <- df[m1[,1]] - df[m1[,2]]
上述所有内容,
ID A_w B_w C_w A_b B_b C_b A_c B_c C_c 1 1 3 4 6 0.5 0.2 0.9 2.5 3.8 5.1 2 2 6 5 7 1.4 3.2 7.6 4.6 1.8 -0.6 3 3 12 11 27 5.4 3.2 6.1 6.6 7.8 20.9
答案 1 :(得分:0)
使用tidyr
和dplyr
即可:
library(tidyr)
library(dplyr)
df1 <- read.table(text="ID A_w B_w C_w A_b B_b C_b
1 3 4 6 0.5 0.2 0.9
2 6 5 7 1.4 3.2 7.6
3 12 11 27 5.4 3.2 6.1",header=T,stringsAsFactors=F)
df1 %>% gather(var,val,-ID) %>%
separate(var,c("var1","var2")) %>%
spread(var2,val) %>%
mutate(c=w-b) %>%
gather(var2,val,-ID,-var1) %>%
unite(var,c("var1","var2")) %>%
spread(var,val)
ID A_b A_c A_w B_b B_c B_w C_b C_c C_w
1 1 0.5 2.5 3 0.2 3.8 4 0.9 5.1 6
2 2 1.4 4.6 6 3.2 1.8 5 7.6 -0.6 7
3 3 5.4 6.6 12 3.2 7.8 11 6.1 20.9 27