2017-08-30 30 views
1

请原谅我试图在R中使用我的excel逻辑,但我似乎无法弄清楚这一点。在一个函数中,给定X,我试图找出它之前的行是否具有更大的值,或者不使用简单的逻辑。如果是的话,如果不是“否”,则在新列中显示为“是”。r - lapply,ifelse并试图在一列中比较行与前一行

这里是样本数据:

temp <- data 
GetFUNC<- function(x){ 
     temp <- cbind(temp, NewCol = ifelse(temp[2:nrow(temp),8] > temp[1:(nrow(temp)-1),8], "yes","no")) 
     write.csv(temp, file = paste0(x,".csv")) 
} 
lapply(example,GetFUNC) 

只是让你可以看到第8列,它看起来是这样的:

testdata$numbers 
[1] 32216510 10755328 8083097 6878500 8377025 6469979 10675856 8189887 5337239 
[10] 5156737 

错误:

Error in data.frame(..., check.names = FALSE) : 
    arguments imply differing number of rows: 11, 10 

感谢任何见解你可以提供!

+1

您的NewCol缺少第一个元素。你可以试试'NewCol = c(NA,ifelse [2:...)'。另外,你在哪里使用'x'?什么是“示例”? –

+0

另外,请看'?diff' - 它将返回值之间的差异。所以你可以做'c(NA,diff(nums)<0)'。 – thelatemail

回答

3

有几个问题:

  • 你不需要lapply,因为使用的是已经矢量的所有操作。
  • :-(见?Syntax)更紧密地结合,因此1:(nrow(temp)-1意味着(1:(nrow(temp))-1。你想1:(nrow(temp)-1)例如,比较这些:

    3:5-1 
    ## [1] 2 3 4 
    
    (3:5) - 1 # same 
    ## [1] 2 3 4 
    
    3:(5-1) # different 
    ## [1] 3 4 
    
  • 即使是最后一个被纠正了ifelse表达

    返回一个载体,它比TESTDATA行数较小的一个。在开始时添加一个NA。

1)甚至更​​好的是此假设输入数据帧是testdata和定义为在端部的注:

transform(testdata, NewCol = c(NA, ifelse(diff(numbers) < 0, "yes", "no"))) 

给予:

numbers NewCol 
1 32216510 <NA> 
2 10755328 yes 
3 8083097 yes 
4 6878500 yes 
5 8377025  no 
6 6469979 yes 
7 10675856  no 
8 8189887 yes 
9 5337239 yes 
10 5156737 yes 

2)以上可能是你想要的,但这里是在动物园包中使用rollapplyr的第二种解决方案。它需要一个长度为2的滚动窗口,并在每个填充NA的第一个值上执行diff。

library(zoo) 

transform(testdata, New = ifelse(rollapplyr(numbers, 2, diff, fill = NA) < 0, "yes", "no")) 

注:输入testdata在重现的形式是:

testdata <- data.frame(numbers = c(32216510, 10755328, 8083097, 6878500, 
    8377025 , 6469979, 10675856, 8189887, 5337239, 5156737)) 
+0

我最喜欢解决方案1,但它不适用于乐器。当我在上面的函数中尝试它时,它会为每一行返回“no”。但是,如果我像你在那里列出的那样隔离它,它就可以正常工作。有什么建议么? – frameworkgeek

+0

如果你的问题是为testdata的数字列中的每个元素产生一个yes或no,那么,如答案顶部所述,你不需要'lapply'。如果问题出现,请澄清。 –

+0

我的错,我遗漏了保存为CSV的乐谱中的一个步骤。所以我希望它能在lapply内工作。 – frameworkgeek

0

下面是使用lag看以前的行和mutate添加新列dplyr解决方案。

library(dplyr) 
df1 <- data.frame(numbers = c(32216510, 10755328, 8083097, 6878500, 8377025, 
           6469979, 10675856, 8189887, 5337239, 5156737)) 

df1 %>% 
    mutate(NewCol = ifelse(lag(numbers) > numbers, "yes", "no")) 

    numbers NewCol 
1 32216510 <NA> 
2 10755328 yes 
3 8083097 yes 
4 6878500 yes 
5 8377025  no 
6 6469979 yes 
7 10675856  no 
8 8189887 yes 
9 5337239 yes 
10 5156737 yes