将日期字符串转换为R中的天数

时间:2019-05-16 01:59:48

标签: r string function dataframe gsub

我有一个数据框,其中的一列表示被称为num_days的天数,即“ 0”,“'',“ 0xY0xM”,“ 0xM”,我想将其更改为天数。

这就是数据框的样子

| a | b | num_days | d  |
| 2 | 3 | '01Y'    | 99 |
| 2 | 4 |  ""      |  8 |
| 3 | 7 | "01Y02M" | 7  |
| 4 | 1 |  "0"     | 8  |

每年Y代表365天,每个月代表30天

| a | b | num_days | d  |
| 2 | 3 |   365    | 99 |
| 2 | 4 |   0      |  8 |
| 3 | 7 |   425    | 7  |
| 4 | 1 |   0      | 8  |

当前这是解决方案:

return_days <- function(x){
  if(x == ""){
      return(0)
  }
  d = gsub("Y", ".", x=x, ignore.case=FALSE, fixed=TRUE)
  d = gsub("M", "" , x=d, ignore.case=FALSE, fixed=TRUE)
  d = strsplit(d, '[.]')
  return( ifelse(length(d[[1]]) == 1, 30*as.numeric(x[[1]][1]), 30* as.numeric(d[[1]][1]) + 365*as.numeric(d[[1]][2]) ) ) 
}

我确信这可以写得更好,但是不幸的是我还不是R向导。任何帮助表示赞赏。谢谢

3 个答案:

答案 0 :(得分:2)

这是使用webView.evaluateJavaScript("document.body.remove()") >>> def print_sameline(): ... list = [1,2,3] ... print("List: ",end="") ... print(*list,sep=",") ... >>> print_sameline() List: 1,2,3 的基本R方法。我们可以尝试将eval替换为sub,将Y替换为*365。这将生成文字算术表达式,其值为天数。然后,我们可以使用M来评估该表达式。

*30

答案 1 :(得分:1)

选项为namespace testapp { class Program { static void Main(string[] args) { string inputFile = args[0]; string inputPlane = args[1]; string inputTime = args[2]; // Check for output flag "-o" bool checkForOutput = Array.Exists(args, element => element == "-o"); if (File.Exists(inputFile) && checkForOutput == true) { //================== Get inputFile formatted ================== List<string> lines = File.ReadAllLines(inputFile).ToList(); // Read text and put into list string words = lines.Aggregate((i, j) => i + " " + j).ToString(); // Split into sentences string[] splitWords = words.Split(); // Each individual word int listLength = lines.Count; // Count total lines string[] stations = new string[listLength]; //================== Get plane file formatted ================== List<string> planeLines = File.ReadAllLines(inputPlane).ToList(); // Read text and put into list string planeElements = planeLines.Aggregate((i, j) => i + " " + j).ToString(); string[] stringPlaneSpec = planeElements.Split(); int[] intPlaneSpec = new int[stringPlaneSpec.Length]; for (int n = 0; n < stringPlaneSpec.Length; n++) intPlaneSpec[n] = int.Parse(stringPlaneSpec[n]); //================== Store station Details ================== Station[] stationDetails = new Station[listLength]; int stationCounter = 0; while (stationCounter < listLength) { for (int i = 0; i < splitWords.Length; i += 3) { stationDetails[stationCounter] = new Station(splitWords[i], Convert.ToInt32(splitWords[i + 1]), Convert.ToInt32(splitWords[i + 2])); stationCounter++; } } List<Station> stationNamesList = stationDetails.ToList(); //================== Store station names ================== string[] names = new string[listLength]; int nameCounter = 0; while (nameCounter < listLength) { for (int i = 0; i < splitWords.Length; i += 3) { names[nameCounter] = (splitWords[i]); nameCounter++; } } //================== Store plane details ================== Plane plane1 = new Plane(intPlaneSpec[0], intPlaneSpec[1], intPlaneSpec[2], intPlaneSpec[3], intPlaneSpec[4]); //================== Store distance totals between position [i] & [i + 1] ================== double[] distanceTotal = new double[listLength]; for (int i = 0; i < stationDetails.Length - 1; i++) { distanceTotal[i] = Math.Round(Station.Distance((stationDetails[i].XValue), (stationDetails[i + 1].XValue), (stationDetails[i].YValue), (stationDetails[i + 1].YValue)), 4); } int lastStation = stationDetails.GetUpperBound(0); // Store last distance total distanceTotal[lastStation] = Math.Round(Station.Distance((stationDetails[lastStation].XValue), (stationDetails[0].XValue), (stationDetails[lastStation].YValue), (stationDetails[0].YValue)), 4); //================== Setup list for storing times ================== DateTime startTime = DateTime.Parse(inputTime); List<DateTime> temporaryTimes = new List<DateTime>(); temporaryTimes.Add(startTime); // Add initial value "23:00 List<string> timeStrings = new List<string>(); for (int i = 0; i < distanceTotal.Length; i++) { temporaryTimes.Add(startTime.AddMinutes((Tour.CalTime(distanceTotal[i], plane1)))); string stringVersion = startTime.ToString(@"hh\:mm"); timeStrings.Add(stringVersion); startTime = (startTime.AddMinutes((Tour.CalTime(distanceTotal[i], plane1)))); } //================== Store total duration of trip ================== int last = (temporaryTimes.Count); TimeSpan totalTime = temporaryTimes[last - 1] - temporaryTimes[0]; //================== Setup list for storing tour names ================== List<string> tourNames = new List<string>(); //================== Output to Console Window & file ================== // Setup output file string outputFile = args[4]; FileStream outFile = new FileStream(outputFile, FileMode.Create, FileAccess.Write); StreamWriter writer = new StreamWriter(outFile); Console.WriteLine("Reading input from {0}", inputFile); if (totalTime.Days >= 1) { Console.WriteLine("Tour time: {0} days {1} hours {2} minutes", totalTime.Days, totalTime.Hours, totalTime.Minutes); } else { Console.WriteLine("Tour time: {0} hours {1} minutes", totalTime.Hours, totalTime.Minutes); } Console.WriteLine("Optimising tour length: Level 1..."); Console.WriteLine("Tour length: {0}", distanceTotal.Sum()); // sum of trip writer.WriteLine(distanceTotal.Sum()); // write sum to output file for (int i = 0; i < stationDetails.Length - 1; i++) { Console.WriteLine("{0}\t->\t{1}\t{2}", stationDetails[i].StationName.Substring(0, 2), stationDetails[i + 1].StationName.Substring(0, 2), distanceTotal[i]); // Store names to tour names tourNames.Add(stationDetails[i].StationName.Substring(0, 2)); tourNames.Add(stationDetails[i + 1].StationName.Substring(0, 2)); writer.WriteLine("{0}\t->\t{1}\t{2}", stationDetails[i].StationName.Substring(0, 2), stationDetails[i + 1].StationName.Substring(0, 2), Math.Round(Station.Distance((stationDetails[i].XValue), (stationDetails[i + 1].XValue), (stationDetails[i].YValue), (stationDetails[i + 1].YValue)), 4)); } // Write Last distance to console Console.WriteLine("{0}\t->\t{1}\t{2}", stationDetails[lastStation].StationName.Substring(0, 2), stationDetails[0].StationName.Substring(0, 2), distanceTotal[lastStation]); //================== Store tour Details in object ================== Tour tour1 = new Tour(4.2, plane1, tourNames, temporaryTimes, totalTime); ////================== Algorithm ================== //// Empty tour with post office initially added List<Station> stationsLeft = stationDetails.ToList(); List<Station> fuckingDone = Tour.SimpleHueristic(stationsLeft); foreach (Station var in fuckingDone) { Console.WriteLine("{0} {1} {2}", var.StationName, var.XValue, var.YValue); } // Write last distance to output file writer.WriteLine("{0}\t->\t{1}\t{2}", stationDetails[lastStation].StationName.Substring(0, 2), stationDetails[0].StationName.Substring(0, 2), Math.Round(Station.Distance((stationDetails[lastStation].XValue), (stationDetails[0].XValue), (stationDetails[lastStation].YValue), (stationDetails[0].YValue)), 4)); // Close output file writer.Close(); outFile.Close(); } //================== END OF IF STATEMENT - NEXT SECTION OF CODE (NEEDS TO BE THE SAME) ================ else if (File.Exists(inputFile) && checkForOutput == false) { //================== Get inputFile formatted ================== List<string> lines = File.ReadAllLines(inputFile).ToList(); // Read text and put into list string words = lines.Aggregate((i, j) => i + " " + j).ToString(); // Split into sentences string[] splitWords = words.Split(); // Each individual word int listLength = lines.Count; // Count total lines string[] stations = new string[listLength]; //================== Get plane file formatted ================== List<string> planeLines = File.ReadAllLines(inputPlane).ToList(); // Read text and put into list string planeElements = planeLines.Aggregate((i, j) => i + " " + j).ToString(); string[] stringPlaneSpec = planeElements.Split(); int[] intPlaneSpec = new int[stringPlaneSpec.Length]; for (int n = 0; n < stringPlaneSpec.Length; n++) intPlaneSpec[n] = int.Parse(stringPlaneSpec[n]); //================== Store station Details ================== Station[] stationDetails = new Station[listLength]; int stationCounter = 0; while (stationCounter < listLength) { for (int i = 0; i < splitWords.Length; i += 3) { stationDetails[stationCounter] = new Station(splitWords[i], Convert.ToInt32(splitWords[i + 1]), Convert.ToInt32(splitWords[i + 2])); stationCounter++; } } //================== Store plane details ================== Plane plane1 = new Plane(intPlaneSpec[0], intPlaneSpec[1], intPlaneSpec[2], intPlaneSpec[3], intPlaneSpec[4]); //================== Store time details ================== DateTime newTime = DateTime.Parse(inputTime); string formatedTime = newTime.ToString("HH:mm"); //================== Store distance totals between position [i] & [i + 1] ================== double[] distanceTotal = new double[listLength]; for (int i = 0; i < stationDetails.Length - 1; i++) { distanceTotal[i] = Math.Round(Station.Distance((stationDetails[i].XValue), (stationDetails[i + 1].XValue), (stationDetails[i].YValue), (stationDetails[i + 1].YValue)), 4); } int lastStation = stationDetails.GetUpperBound(0); // Store last distance total distanceTotal[lastStation] = Math.Round(Station.Distance((stationDetails[lastStation].XValue), (stationDetails[0].XValue), (stationDetails[lastStation].YValue), (stationDetails[0].YValue)), 4); //================== Setup list for storing times ================== List<DateTime> temporaryTimes = new List<DateTime>(); //================== Setup list for storing tour names ================== List<string> tourNames = new List<string>(); //================== Output to only Console ================== Console.WriteLine("Reading input from {0}", inputFile); Console.WriteLine("Optimising tour length: Level 1..."); Console.WriteLine("Tour length: {0}", distanceTotal.Sum()); // sum of trip for (int i = 0; i < stationDetails.Length - 1; i++) { Console.WriteLine("{0}\t->\t{1}\t{2}", stationDetails[i].StationName.Substring(0, 2), stationDetails[i + 1].StationName.Substring(0, 2), distanceTotal[i]); } // Output last distance back to post office Console.WriteLine("{0}\t->\t{1}\t{2}", stationDetails[lastStation].StationName.Substring(0, 2), stationDetails[0].StationName.Substring(0, 2), distanceTotal[lastStation]); } else { //========== Display error message if input is incorrect ============ Console.WriteLine("Invalid Input"); } Console.ReadLine(); } } }

<form #form action="//[businessname].[dc].list-manage.com/subscribe/post?u=[list]&amp;id=39c3c32163" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>

<input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button button-positive button-block" (click)="form.submit()">

或使用gsubfn

library(gsubfn)
i1 <- !df1$num_days  %in% c("", 0)
df1$num_days[i1] <-sapply(gsub("\\+$", "", gsubfn("[A-Z]", 
       list(Y= '*365+', M = '*30'),
       df1$num_days[i1])), function(x) eval(parse(text = x)))

数据

tidyverse

答案 2 :(得分:1)

试一下:

ifelse(substring(df$num_days, 3, 3) == "Y",
       365 * as.numeric(substring(df$num_days, 1, 2)) +
           30 * as.numeric(substring(df$num_days, 4, 5)),
       30 * as.numeric(substring(df$num_days, 1, 2)))