我希望有一个等效的Excel函数“if”。这似乎很基本,但我找不到相关的帮助。
如果不同列中的两个后续单元格不相同,我想评估特定单元格的“NA”。在Excel中,命令将如下(例如在C1中):if(A1 = A2,B1,“NA”)。然后我只需将其扩展到列的其余部分。
但在R中,我被困住了!
到目前为止,这是我的R代码的等价物。
df = data.frame(Type = c("1","2","3","4","4","5"),
File = c("A","A","B","B","B","C"))
df
为了在另一列中获得每个Type的以下类型,我在StackOverflow上找到了一个有用的函数来完成这项工作。
# determines the following Type of each Type
shift <- function(x, n){
c(x[-(seq(n))], rep(6, n))
}
df$TypeFoll <- shift(df$Type, 1)
df
现在,当这行的文件与下一行的文件相同时,我想将TypeFoll保留在特定的行中。
这是我尝试过的。它失败了!
for(i in 1:length(df$File)){
df$TypeFoll2 <- ifelse(df$File[i] == df$File[i+1], df$TypeFoll, "NA")
}
df
最后,我的数据框应如下所示:
aim = data.frame(Type = c("1","2","3","4","4","5"),
File = c("A","A","B","B","B","C"),
TypeFoll = c("2","3","4","4","5","6"),
TypeFoll2 = c("2","NA","4","4","NA","6"))
aim
哦,顺便说一句,如果有人知道如何轻松地将TypeFoll和TypeFoll2列放在Type Type之后,那就太棒了!
提前致谢
答案 0 :(得分:1)
我会这样做(不保留移位函数的结果)
df = data.frame(Type = c("1","2","3","4","4","5"),
File = c("A","A","B","B","B","C"), stringsAsFactors = FALSE)
# This is your shift function
len=nrow(df)
A1 <- df$File[1:(len-1)]
A2 <- df$File[2:len]
# Why do you save the result of the shift function in the df?
然后分配if(A1 = A2, B1, "NA")
。正如akrun提到的ifelse
是矢量化的:顺便说一句。这是将列附加到data.frame
df$TypeFoll2 <- c(ifelse(A1 == A2, df$Type, NA), 6) #Why 6?
因为6这里的硬编码类似于:
df$TypeFoll2 <- c(ifelse(A1 == A2, df$Type, NA), max(df$Type)+1)
更通用。
答案 1 :(得分:0)
首先,&#39;对于&#39; R中的循环非常慢,所以请尝试将其视为向量操作。
df = data.frame(Type = c("1","2","3","4","4","5"),
File = c("A","A","B","B","B","C"));
创建已移位的类型和文件并将其放在新列中:
df$TypeFoll = c(as.character(df$Type[2:nrow(df)]), "NA");
df$FileFoll = c(as.character(df$File[2:nrow(df)]), "NA");
现在,df看起来像这样:
> df
Type File TypeFoll FileFoll
1 1 A 2 A
2 2 A 3 B
3 3 B 4 B
4 4 B 4 B
5 4 B 5 C
6 5 C NA NA
然后,通过组合这些来创建TypeFoll2:
df$TypeFoll2 = ifelse(df$File == df$FileFoll, df$TypeFoll, "NA");
你应该有一些看起来很像你想要的东西:
> df;
Type File TypeFoll FileFoll TypeFoll2
1 1 A 2 A 2
2 2 A 3 B NA
3 3 B 4 B 4
4 4 B 4 B 4
5 4 B 5 C NA
6 5 C NA NA NA
如果要删除FileFoll列: df $ FileFoll = NULL;